我在理解浮点类型的精度时遇到问题。msdn将该精度写入6 到 9 位数字。但我注意到精度取决于数字的大小:
float smallNumber = 1.0000001f;
Console.WriteLine(smallNumber); // 1.0000001
bigNumber = 100000001f;
Console.WriteLine(bigNumber); // 100000000
Run Code Online (Sandbox Code Playgroud)
smallNumber 比 big 更精确,我了解 IEEE754,但我不明白 MSDN 如何计算精度,这是否有意义?
此外,您可以在此处使用浮点格式的数字表示。请在“您输入”输入中输入 100000000 值,然后单击右侧的“+1”。然后将输入的值更改为 1,并再次单击“+1”。您可能会看到精度上的差异。
如果x和y是 IEEE 754 浮点数(单精度或双精度),我们可以有
x * y == y
Run Code Online (Sandbox Code Playgroud)
其中x != 1and y != 0(and nory等于+inf, -inf, or nan)。
我知道可以正确比较的整数范围是-(2^53 - 1)到2^53 - 1。
但是浮点数的范围是多少呢?
// Should the double type conform to this specification? I guess
double c = 9007199254740990.9;
double d = 9007199254740990.8;
System.out.println(c > d); // return false
Run Code Online (Sandbox Code Playgroud) 看起来JavaScript的number类型与C和C++的double类型完全相同,并且都是IEEE 754-1985。
JavaScript 可以使用 IEEE 754 作为整数,但是当数字变大或进行算术计算(例如除以10或 by )时3,它似乎可以切换到浮点模式。现在,C 和 C++ 仅使用 IEEE 754 作为double,因此仅使用浮点部分,而不使用“整数”部分。因此,C 和 C++ 是否未使用整数表示形式?
(C 未使用NaN, Infinite, -Infinite,-0因为我记得在 C 中从未使用过它们)。
我知道,为了检查两个双精度数之间的相等性,您必须使用数字之间的绝对差,并将此差值与小于 1 且大于零的数字进行比较。这是最简单的方法,因为还有更复杂的方法。我的一位同事说,例如,如果您使用 Math.Round 表示 2 个小数位,则可以使用精确相等,而无需使用上述方法。例如,如果你有号码double x;和号码,double y;你可以写
double x1=Math.Round(x,2);
double y1=Math.Round(y,2);
if(x1 == y1)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
我认为这不是真的。但你能告诉我为什么这是对还是错?
假设a,x和y是正的IEEE浮点数, x < y.证明a × x < a × y其中×表示浮点乘法舍入到最近.
天真地,你可能会认为对于某些a和x接近y,你会得到一个 × x = a × y.事实证明,这不可能发生(只要不包括非规范化数字,无穷大和NaN).
我对一个优雅的证据感兴趣,如果可能的话,我会给出一本书或纸.
TAKE 2:正如Pascal Cuoq的回复所示,上述陈述是错误的.y = 1 的受限制版本怎么样?以下是要证明的陈述:
假设a和x是正的IEEE浮点数, x <1.证明a × x < a其中×表示浮点乘法舍入到最接近.
为了比较Go中的两个浮点数(float64)是否相等,我对IEEE 754的表面理解和浮点数的二进制表示使我认为这是一个很好的解决方案:
func Equal(a, b float64) bool {
ba := math.Float64bits(a)
bb := math.Float64bits(b)
diff := ba - bb
if diff < 0 {
diff = -diff
}
// accept one bit difference
return diff < 2
}
Run Code Online (Sandbox Code Playgroud)
问题是:这是一种更通用,更精确,更有效的方法来比较两个任意大或小的浮动"几乎相等",而不是旧的abs(diff) < epsilon黑客?我的理由是,如果一个人只允许二进制表示中的一个比特差异,那么除了严格的相等之外,比较的数字肯定不会更加相等,显然(如评论中所指出的)可以用==浮点数来检查.
注意:我已编辑问题以使其更清晰.
由于0.0 / 0.0在数学上未定义,IEEE-754 浮点标准合理地定义了NaN其结果。现在,因为与 不同infinity,NaN不是一个明确定义的值,而是一组值,因此是否0.0 / 0.0是一个明确定义的常量的问题也是合理的。
值得一提的是x / 0.0,infinity如果x != 0.0.
IEEE-754 浮点标准中是否有0.0 / 0.0明确定义的常量值?NaN换句话说,它是否具有明确定义的位模式?
language-agnostic floating-point nan numerical-computing ieee-754
如上所述,我想找到-1x10 ^ 200的IEEE 754表示.
我知道我们可以得到标志为1,因为我们有一个负数.但是我不确定如何找到尾数/指数.我最初的想法是将10 ^ 200转换为2 ^ x.但是x不是整数.所以我认为我们需要以某种方式通过以某种方式分离10 ^ 200得到一个分数.从理论上讲,人们可以使用非常长的分离,但我正在寻找一个更优雅的答案,可以在没有高精度计算器的情况下完成.
据我所知 int64 可以在 Go 中的 float64 中转换,语言允许使用float64(some_int64_variable),但我也知道并非所有 64 位有符号整数都可以用 double 表示(因为 IEE754 近似值)。
我们有一些代码可以使用美分接收商品的价格int64并执行类似的操作
const TB = 1 << 40
func ComputeSomething(numBytes int64) {
Terabytes := float64(numBytes) / float64(TB)
Run Code Online (Sandbox Code Playgroud)
我想知道这有多安全,因为并非所有整数都可以用双精度表示。