标签: precision

浮点数学在C#中是否一致?是真的吗?

不,这不是另一个"为什么是(1/3.0)*3!= 1"的问题.

我最近一直在读关于漂浮点的事情; 具体而言,相同的计算如何在不同的体系结构或优化设置上给出不同的结果.

对于存储重放的视频游戏来说,这是一个问题,或者是对等网络(而不是服务器 - 客户端),它依赖于每次运行程序时产生完全相同结果的所有客户端 - 一个小的差异浮点计算可能导致不同机器(甚至是同一台机器上)的游戏状态截然不同!

甚至在"跟随" IEEE-754的处理器中也会发生这种情况,这主要是因为某些处理器(即x86)使用双倍扩展精度.也就是说,它们使用80位寄存器进行所有计算,然后截断为64位或32位,导致与使用64位或32位进行计算的机器不同的舍​​入结果.

我在网上看到过这个问题的几种解决方案,但都是针对C++,而不是C#:

  • double使用_controlfp_s(Windows),_FPU_SETCW(Linux?)或fpsetprec(BSD)禁用双扩展精度模式(以便所有计算使用IEEE-754 64位).
  • 始终使用相同的优化设置运行相同的编译器,并要求所有用户具有相同的CPU架构(无跨平台播放).因为我的"编译器"实际上是JIT,它可能在每次运行程序时都有不同的优化,我认为这是不可能的.
  • 使用定点算术,避免floatdouble完全.decimal可以用于此目的,但会慢得多,并且没有任何System.Math库函数支持它.

那么,这在C#中是否也是一个问题? 如果我只打算支持Windows(而不是Mono)怎么办?

如果是,有没有办法强制我的程序以正常的双精度运行?

如果没有,是否有任何库可以帮助保持浮点计算的一致性?

.net c# floating-point precision ieee-754

152
推荐指数
6
解决办法
1万
查看次数

单精度和双精度浮点运算有什么区别?

单精度浮点运算和双精度浮点运算有什么区别?

我对与视频游戏机有关的实用术语特别感兴趣.例如,Nintendo 64是否具有64位处理器,如果确实如此,则意味着它能够进行双精度浮点运算?PS3和Xbox 360能否实现双精度浮点运算或单精度运算,一般情况下使用双精度功能(如果存在?).

floating-point precision operations processor

149
推荐指数
7
解决办法
27万
查看次数

为什么多次添加0.1会保持无损?

我知道0.1十进制数不能用有限的二进制数(解释)精确表示,所以double n = 0.1会失去一些精度而不会完全正确0.1.另一方面0.5可以完全表示,因为它是0.5 = 1/2 = 0.1b.

已经说过,添加0.1 三次不会完全给出0.3以下代码打印是可以理解的false:

double sum = 0, d = 0.1;
for (int i = 0; i < 3; i++)
    sum += d;
System.out.println(sum == 0.3); // Prints false, OK
Run Code Online (Sandbox Code Playgroud)

但是,如何增加0.1 五次才会给出确切的答案0.5呢?以下代码打印true:

double sum = 0, d = 0.1;
for (int i = 0; i < 5; i++)
    sum += …
Run Code Online (Sandbox Code Playgroud)

java floating-point precision double

148
推荐指数
2
解决办法
1万
查看次数

在Java中保留double的精度

public class doublePrecision {
    public static void main(String[] args) {

        double total = 0;
        total += 5.6;
        total += 5.8;
        System.out.println(total);
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码打印:

11.399999999999
Run Code Online (Sandbox Code Playgroud)

我怎么才能打印(或能够用它)11.4?

java floating-point precision double

134
推荐指数
11
解决办法
19万
查看次数

toFixed()和toPrecision()之间的区别?

我是JavaScript的新手,刚刚发现toFixed()toPrecision()编号.但是,我无法弄清楚两者之间的区别是什么.

number.toFixed()和之间有什么区别number.toPrecision()

javascript precision rounding

115
推荐指数
6
解决办法
5万
查看次数

应该添加浮点数以获得最精确的结果?

这是我在最近的采访中被问到的一个问题,我想知道(我实际上并不记得数值分析的理论,所以请帮助我:)

如果我们有一些累积浮点数的函数:

std::accumulate(v.begin(), v.end(), 0.0);
Run Code Online (Sandbox Code Playgroud)

vstd::vector<float>例如,是一个.

  • 在累积它们之前对这些数字进行排序会更好吗?

  • 哪个订单会给出最准确的答案?

我怀疑按升序排序数字实际上会减少数值误差,但不幸的是我无法证明这一点.

PS我确实意识到这可能与现实世界的编程无关,只是好奇.

c++ floating-point precision

105
推荐指数
4
解决办法
1万
查看次数

控制R中打印输出的小数位数

R中有一个选项可以控制数字显示.例如:

options(digits=10)
Run Code Online (Sandbox Code Playgroud)

应该给计算结果10位数,直到R会话结束.在R的帮助文件中,digits参数的定义如下:

digits:控制打印数值时要打印的位数.这只是一个建议.有效值为1 ... 22,默认值为7

所以,它说这只是一个建议.如果我想总是显示10位数而不是更多或更少,该怎么办?

我的第二个问题是,如果我想显示超过22位数,即更精​​确的计算如100位数,该怎么办?是否可以使用基础R,或者我是否需要额外的包/功能?

编辑:感谢jmoy的建议,我尝试了sprintf("%.100f",pi)它给了

[1] "3.1415926535897931159979634685441851615905761718750000000000000000000000000000000000000000000000000000"
Run Code Online (Sandbox Code Playgroud)

它有48位小数.这是R可以处理的最大限制吗?

precision r digits output-formatting r-faq

103
推荐指数
2
解决办法
21万
查看次数

将浮点值的相等性检查为0是否安全?

我知道你不能正常依赖双重或十进制类型值之间的相等,但我想知道0是否是特殊情况.

虽然我可以理解0.00000000000001和0.00000000000002之间的不精确,但0本身似乎很难搞砸,因为它什么都没有.如果你对什么都不精确,那就不再是什么了.

但我对这个话题知之甚少,所以我不能说.

double x = 0.0;
return (x == 0.0) ? true : false;
Run Code Online (Sandbox Code Playgroud)

这会永远回归真实吗?

.net c# floating-point precision zero

97
推荐指数
5
解决办法
7万
查看次数

0.0到1.0之间有多少个双数?

这是我多年来一直想到的事情,但我从来没有花时间问过.

许多(伪)随机数生成器生成0.0到1.0之间的随机数.在数学上,此范围内有无限数,但是double是浮点数,因此具有有限的精度.

所以问题是:

  1. double在0.0和1.0之间有多少个数字?
  2. 是否有1到2之间的数字?100到101之间?在10 ^ 100和10 ^ 100 + 1之间?

注意:如果它有所不同,我double特别感兴趣的是Java的定义.

random floating-point precision double

92
推荐指数
3
解决办法
8726
查看次数

C#DateTime.Now精度

我在进行一些单元测试时遇到了DateTime.UtcNow的一些意外行为.看起来当你快速连续调用DateTime.Now/UtcNow时,它似乎会给你一个长于预期的时间间隔的相同值,而不是捕获更精确的毫秒增量.

我知道有一个秒表类更适合做精确的时间测量,但我很好奇是否有人可以在DateTime中解释这种行为?是否有针对DateTime.Now记录的官方精度(例如,精确到50毫秒内?)?为什么DateTime.Now会不像大多数CPU时钟那样精确?也许它只是为最低公分母CPU而设计的?

public static void Main(string[] args)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    for (int i=0; i<1000; i++)
    {
        var now = DateTime.Now;
        Console.WriteLine(string.Format(
            "Ticks: {0}\tMilliseconds: {1}", now.Ticks, now.Millisecond));
    }

    stopwatch.Stop();
    Console.WriteLine("Stopwatch.ElapsedMilliseconds: {0}",
        stopwatch.ElapsedMilliseconds);

    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

.net c# precision datetime time-precision

91
推荐指数
5
解决办法
5万
查看次数