一、BigDecimal保留两位小数及格式化成百分比

在项目中经常会用到小数的一些计算,而float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确。所以有时候必须要采用BigDecimal。

public class Demo {
   public static void main(String[] args) {
  BigDecimal a =null;
  Integer faultRate = 6;
  a = BigDecimal.valueOf(faultRate.doubleValue()/3);
  BigDecimal  b =a.setScale(2, RoundingMode.HALF_UP);//保留两位小数
  System.out.println("结果是"+b);
  //下面将结果转化成百分比
  NumberFormat percent = NumberFormat.getPercentInstance();
       percent.setMaximumFractionDigits(2);


       System.out.println(percent.format(b.doubleValue()));
  
}
}

运行结果是:

BigDecimal.setScale()方法用于格式化小数点
setScale(1)表示保留一位小数,默认用四舍五入方式 
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4

setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍

setScaler(1,BigDecimal.ROUND_CEILING)接近正无穷大的舍入

setScaler(1,BigDecimal.ROUND_FLOOR)接近负无穷大的舍入,数字>0和ROUND_UP作用一样,数字<0和ROUND_DOWN作用一样

setScaler(1,BigDecimal.ROUND_HALF_EVEN)向最接近的数字舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。


 
注释:
1:scale指的是你小数点后的位数。比如123.456则score就是3.
score()就是BigDecimal类中的方法啊。
比如:BigDecimal b = new BigDecimal("123.456");
b.scale(),返回的就是3.
2:roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。
3:pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!
4:对于一般add、subtract、multiply方法的小数位格式化如下:

BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println("mData=" + mData);
----结果:----- mData=9.66

二、使用DecimalFormat,保留小数点后两位

public static void main(String[] args) {
       DecimalFormat format = new DecimalFormat("0.00");
       String abc ="100.456";
       String a = format.format(new BigDecimal(abc));
       System.out.println(a);
   }

在这里说明一下,java的两个整型数字相除不准确,比如5/6得到的结果会是0,你需要至少转化其中一个为浮点型再相除

这样就正常了。

其实还可以用stringformat来转换,在这里扩充一下stringformat的用法:

在开发的时候一段字符串的中间某一部分是需要可变的 比如一个Textview需要显示”XXX用户来自 上海 年龄 21 性别 男” 
其中的 XXX 是用户名 每个用户也是不一样的 
地区 上海 为可变的string数据 
年龄 21 为可变的int数据 
性别 男 为可变的string数据 
遇到这种情况你们是怎么样解决的呢?把这段字符串保存在常量类里吗?不!我们应该遵循Google的开发模式

XML

<string name="user_info'> %1$s</span> 用户来自 <span class="hljs-variable">%2</span><span class="hljs-variable">$s  年龄 %3$d</span>  性别 <span class="hljs-variable">%4</span><span class="hljs-variable">$s</string>  
  • 1

JAVA

 
  1. String userName="XXX";

  2. String userProvince="上海";

  3. int userAge=21;

  4. String userSex="男";

  5. String string=getResources().getString(R.string.user_info);

  6. String userInfo=String.format(string,userName,userProvince,userAge,userSex);

是不是觉得很方便 
本来是打算当笔记记录下来备忘的,但是有朋友有朋友问到的一些相关的东西,我就完善一下吧

String.format()字符串常规类型格式化的两种重载方式

  • format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。
  • format(Locale locale, String format, Object… args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串。

上个栗子有用到了字符类型和整数类型的格式化 下面我把常用的类型例举出来

转换符 详细说明 示例
%s 字符串类型 “喜欢请收藏”
%c 字符类型 ‘m’
%b 布尔类型 true
%d 整数类型(十进制) 88
%x 整数类型(十六进制) FF
%o 整数类型(八进制) 77
%f 浮点类型 8.888
%a 十六进制浮点类型 FF.35AE
%e 指数类型 9.38e+5
%g 通用浮点类型(f和e类型中较短的) 不举例(基本用不到)
%h 散列码 不举例(基本用不到)
%% 百分比类型 %(%特殊字符%%才能显示%)
%n 换行符 不举例(基本用不到)
%tx 日期与时间类型(x代表不同的日期与时间转换符) 不举例(基本用不到)

为了方便理解还是举个例子

 
  1. String str=null;

  2. str=String.format("Hi,%s", "小超");

  3. System.out.println(str);

  4. str=String.format("Hi,%s %s %s", "小超","是个","大帅哥");

  5. System.out.println(str);

  6. System.out.printf("字母c的大写是:%c %n", 'C');

  7. System.out.printf("布尔结果是:%b %n", "小超".equal("帅哥"));

  8. System.out.printf("100的一半是:%d %n", 100/2);

  9. System.out.printf("100的16进制数是:%x %n", 100);

  10. System.out.printf("100的8进制数是:%o %n", 100);

  11. System.out.printf("50元的书打8.5折扣是:%f 元%n", 50*0.85);

  12. System.out.printf("上面价格的16进制数是:%a %n", 50*0.85);

  13. System.out.printf("上面价格的指数表示:%e %n", 50*0.85);

  14. System.out.printf("上面价格的指数和浮点数结果的长度较短的是:%g %n", 50*0.85);

  15. System.out.printf("上面的折扣是%d%% %n", 85);

  16. System.out.printf("字母A的散列码是:%h %n", 'A');

输出结果

 
  1. Hi,小超

  2. Hi,小超 是个 大帅哥

  3. 字母c的大写是:C

  4. 布尔的结果是:false

  5. 100的一半是:50

  6. 100的16进制数是:64

  7. 100的8进制数是:144

  8. 50元的书打8.5折扣是:42.500000 元

  9. 上面价格的16进制数是:0x1.54p5

  10. 上面价格的指数表示:4.250000e+01

  11. 上面价格的指数和浮点数结果的长度较短的是:42.5000

  12. 上面的折扣是85%

  13. 字母A的散列码是:41

###搭配转换符还有实现高级功能 第一个例子中有用到 $

标志 说明 示例 结果
+ 为正数或者负数添加符号 (“%+d”,15) +15
0 数字前面补0(加密常用) (“%04d”, 99) 0099
空格 在整数之前添加指定数量的空格 (“% 4d”, 99) 99
, 以“,”对数字分组(常用显示金额) (“%,f”, 9999.99) 9,999.990000
( 使用括号包含负数 (“%(f”, -99.99) (99.990000)
# 如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0 (“%#x”, 99)(“%#o”, 99) 0x63 0143
< 格式化前一个转换符所描述的参数 (“%f和%<3.2f”, 99.45) 99.450000和99.45
d,%2$s”, 99,”abc”) 99,abc    

第一个例子中有说到 %tx x代表日期转换符 我也顺便列举下日期转换符

标志 说明 示例
c 包括全部日期和时间信息 星期六 十月 27 14:21:20 CST 2007
F “年-月-日”格式 2007-10-27
D “月/日/年”格式 10/27/07
r “HH:MM:SS PM”格式(12时制) 02:25:51 下午
T “HH:MM:SS”格式(24时制) 14:28:16
R “HH:MM”格式(24时制) 14:28

来个例子方便理解

 
  1. Date date=new Date();

  2. //c的使用

  3. System.out.printf("全部日期和时间信息:%tc%n",date);

  4. //f的使用

  5. System.out.printf("年-月-日格式:%tF%n",date);

  6. //d的使用

  7. System.out.printf("月/日/年格式:%tD%n",date);

  8. //r的使用

  9. System.out.printf("HH:MM:SS PM格式(12时制):%tr%n",date);

  10. //t的使用

  11. System.out.printf("HH:MM:SS格式(24时制):%tT%n",date);

  12. //R的使用

  13. System.out.printf("HH:MM格式(24时制):%tR",date);

输出结果

 
  1. 全部日期和时间信息:星期三 九月 21 22:43:36 CST 2016

  2. 年-月-日格式:2016-09-21

  3. 月/日/年格式:16/10/21

  4. HH:MM:SS PM格式(12时制):10:43:36 下午

  5. HH:MM:SS格式(24时制):22:43:36

  6. HH:MM格式(24时制):22:43

String s=String.format("%02d", 1) //1为int类型,0代表前面要补的字符 2代表字符串长度,d表示参数为整数类型