首先,我应该澄清,我问这个问题只是为了得到启发;我并不急于得到一个答案,但一个答案可能会帮助我更欣赏BigDecimal类.

我一直有--现在仍然有--关于小数点后保证只有一定位数的小数值的哲学.以美元数字为例,小数点后的位数保证不超过2位.在为这类应用程序编写代码时,我显然不能使用带有舍入误差的浮点数.相反,我会使用一个整数(或LONG或BigInteger,取决于数字可能达到的高度)来表示美分的数字.例如,我会将$12.34的数字存储和处理为整数1234.只有在输出美元数字时(可能在输入美元数字时),我才会用小数点格式化数字.

但现在我正在读一本介绍BigDecimal类的Java书.它甚至在一些例子中使用了美元数字.我对此不感兴趣,因为我觉得除法可能会很尴尬,除非你知道怎么做.

假设您正在编写一个将美元数字除以的程序.例如,也许许多人想平分这笔钱.比方说,有一天程序运行的参数应该是1.21美元除以3.你会希望程序得出40美分的结果,余数是1美分.换句话说,结果应该是0.40和0.01.如果将数字存储为代表美分数字的整数,则可以很好地工作.但它能与代表美元的BigDecimals一起使用吗?

显然,这段代码不会起作用:

import java.math.BigDecimal;
    
    public class test {
    
        public static void main(String[] args) {
            BigDecimal total = new BigDecimal("1.21");
            BigDecimal divider = new BigDecimal(3);
            BigDecimal results[]= new BigDecimal[2];
            results = total.divideAndRemainder(divider);
    
            for (BigDecimal result : results) System.out.println(result);   
        }
    }

您将得到0.00和1.21的结果,而不是您想要的0.40和0.01.

这本书暗示,解决方案是设定规模.所以我试了试:

    BigDecimal total = new BigDecimal("1.21");
    total = total.setScale(2);
    BigDecimal divider = new BigDecimal(3);
    divider = divider.setScale(2);
    BigDecimal results[]= new BigDecimal[2];
    results = total.divideAndRemainder(divider);

结果仍为0.00和1.21.

也许结果应该放在已经设置了刻度的变量中?我试过了:

    BigDecimal total = new BigDecimal("1.21");
    total = total.setScale(2);
    BigDecimal divider = new BigDecimal(3);
    divider = divider.setScale(2);
    BigDecimal results[]= new BigDecimal[2];
    results[0] = new BigDecimal(0);
    results[0] = results[0].setScale(2);
    results[1] = new BigDecimal(0);
    results[1] = results[0].setScale(2);
    results = total.divideAndRemainder(divider);

那真是太尴尬了!结果仍然是一样的.

当然,我可以将1.21美元乘以100,然后再除以3,然后再除以100,但这将是一个很好的理由,可以首先使用我的整数方法并跳过这些步骤.有没有一种优雅的方式来划分BigDecimal值?或者我应该坚持以整数存储分值?

推荐答案

最根本的问题是您首先使用divideAndRemainder,这并不能实现您想要它做的事情;正如它的文档所指定的那样,它只除以一个整数值--一个"美元"值,不含美分.它类似于divideToIntegralValue,而不是divide:

返回一个由两个元素组成的BigDecimal数组,其中包含DivideToIntegralValue的结果,后跟两个操作数的余数的结果.

您需要改用.divide,假定指定为RoundingMode,然后自己计算余数.

BigDecimal division = total.divide(divisor, RoundingMode.DOWN);
System.out.println(division); // 0.40
System.out.println(total.subtract(division.multiply(divisor))); // 0.01

Java相关问答推荐

Java:根据4象限中添加的行数均匀分布行的公式

为什么Java中的两个日期有差异?

使用Java Streams API比较两个不同的Java集合对象和一个公共属性

Apache POI:使用反射获取zoom 级别

路径映射未发生

是否保证在事务性块的末尾标记违反约束?

如何判断一个矩阵是否为有框矩阵?

试着做一个2x2的魔方求解算法,我如何找到解路径(DFS)?

SpringBoot Kafka自动配置-适用于SASL_PLAYTEXT的SSLBundle 包,带SCRAM-SHA-512

在Eclipse中数组的可空性

MimeMessage emlMessage=new MimeMessage(Session,emlInputStream);抛出InvocationTargetException

使SLF4J在Android中登录到Logcat,在测试中登录到控制台(Gradle依赖问题)

使用正则表达式从字符串中提取多个值

循环不起作用只有第一个元素重复

接受类及其接口的Java类型(矛盾)

如何使用我的RLE程序解决此问题

MapStruct记录到记录的映射不起作用

Java 21保护模式的穷尽性

什么是;u〃;平均值;jdku;在java开发工具包中?

UuidGenerator Bean 类型不匹配?