类BigDecimal
有一些有用的方法来保证无损转换:
但是,方法floatValueExact()和doubleValueExact()不存在。
我阅读了方法FloatValue()
和douleValue()
的OpenJDK源代码。两者似乎都分别回退到Float.parseFloat()
和Double.parseDouble()
,它们可能返回正无穷大或负无穷大。例如,解析10,000个9s的字符串将返回正无穷大。据我所知,BigDecimal
没有无穷大的内部概念。此外,将100个9s的字符串解析为Double
给出了1.0E100
,这不是无穷大,而是失去了精度。
什么是合理的实现?
我考虑了一种通过组合BigDecimal来实现双精度的解决方案。doubleValue(),BigDecial。toString(),双精度。parseDouble(字符串)
和Double。toString(double)
,但看起来很凌乱。我想在这里问一下,因为可能(必须!)更简单的解决方案。
通过读取文档,它对numTypeValueExact变量所做的一切就是检查是否存在小数部分,或者该值是否对于数字类型太大,并引发异常。
对于FloatValue()
和douleValue()
,正在进行类似的溢出检查,但不是抛出异常,而是返回Double.POSITIVE_INFINITY
或Double.NEGATIVE_INFINITY
表示双精度和Float.POSITIVE_INFINITY
或Float.NEGATIVE_INFINITY
表示浮点数。
因此,浮点和double的精确方法的最合理(也是最简单)实现应该只检查转换是否返回正无穷大或负无穷大。
此外,请记住,BigDecimal
旨在处理因对大型非理性使用浮动
或双
而导致的精度不足,因此正如@JB Nizet评论的那样,您可以添加到上面的另一个检查是将双
或浮动
转换回BigDecimal
以查看您是否仍然获得相同的值。这应该证明转换是正确的。
下面是floatValueExact()的这种方法的外观:
public static float floatValueExact(BigDecimal decimal) {
float result = decimal.floatValue();
if (!(Float.isNaN(result) || Float.isInfinite(result))) {
if (new BigDecimal(String.valueOf(result)).compareTo(decimal) == 0) {
return result;
}
}
throw new ArithmeticException(String.format("%s: Cannot be represented as float", decimal));
}
上面使用compareTo
而不是equals
是有意的,以免对检查过于严格。equals
仅当两个BigDecimal
对象具有相同的值和比例(小数部分的大小)时才会评估为true,而compareTo
在无关紧要时会忽略这种差异。例如2.0
vs2.00
。
问题内容: 我有这个问题,我必须将公里转换成英里。我是一个新手程序员,所以请耐心等待。 到目前为止,这是我的代码: 它给我一个错误,说: 问题答案: 您正在尝试将a 设置为变量 要修复,请更改此行 至
我有一个问题,我必须把公里转换成英里。我是一个新手程序员,所以请原谅我。 这是我到目前为止的代码: 它给我一个错误提示:
问题内容: 我有一个浮点数组,我想将其转换为Java中的双精度数组。我知道迭代数组并创建一个新数组的明显方法。我希望Java在希望与double []一起工作的地方能够平稳地消化float [] …,但不能与此一起工作。进行这种转换的优雅,有效的方法是什么? 问题答案: 基本上 , 必须进行每个值的转换。两种数组类型之间没有隐式转换,因为在JITting之后用于处理它们的代码将有所不同- 它们具有
我正在写一个基于无符号整数的图像类。我目前对8位和16位RGBA像素使用uint8_t和uint16_t缓冲,要从16位转换到8位,我只需将16位值除以std::numeric_limits 但是,如果我想要一个图像,每个RGBA分量都是64位无符号整数(我知道,这个数字高得离谱),我该如何在0和1之间找到一个浮点/双精度数,来表示我的像素值在0和最大uint64_t之间有多远呢?我认为转换为do
问题内容: 我正在尝试对.3gpp音频文件执行快速傅立叶变换。该文件包含来自电话麦克风的44100kHz的5秒钟小录音。 出于显而易见的原因,我可以找到的每个Java FFT算法都只接受double [],float []或Complex []输入,但是我以字节数组的形式读取音频文件,因此我有点困惑我从这里去哪里。我唯一能找到的是上一个问题的答案: Android音频FFT使用音频记录检索特定频率
在java中如何将BigDecimal转换为Double?我有一个要求,我们必须使用Double作为参数,但我们得到的是BigDecimal,所以我必须将BigDecimal转换为Double。