函数ceil()、round()、floor()的执行速度 - 页 6

 
Nikolai Semko:

我已经在这里 写过它了。

好的。据我所知,你是在这个终端和给定的精度范围内写作的,你对在任何其他设备或平台上移植和运行代码不感兴趣。

最好的问候。

P.S. 一个好的程序员应该明白,硬件和程序可能会发生变化,你需要避免在未来出现错误。
 
Andrey Kisselyov:
如果你是在给定的终端的范围内,在其准确性的范围内进行写作,那么代码在任何其他设备或平台上的移植和操作对你来说都是没有意义的。

真诚的。

正是如此。我们谈论的是MQL5(也许也是MQL4--我没有检查)。而类或算法内的代码将在MQL内完美转移。但它也能在C++中工作。我已经有了一些例子。

 
Andrey Kisselyov:

P.S. 一个好的程序员必须明白,硬件和程序可能会发生变化,有必要在未来避免错误。 像你这样的任务,你可能在未来不容易发现一个你当时会认为无懈可击的函数中的错误。
在这种情况下,甚至不可能想象你所说的变化。计算(int)(x+0.5)的数学方法可能会有什么变化?它将停止丢弃小数部分 还是什么?
 
Nikolai Semko:
在这种情况下,甚至不可能想象你所说的变化。计算(int)(x+0.5)的数学可以改变什么?它是否会停止掉落小数点的部分

例如,一个新的数据类型 将被引入......。

 
STARIJ:

例如,一个新的数据类型 将被引入......。

)))是的,但如果旧的数据类型被取消,代码将停止工作....
 
我说的是这个烂摊子。
y=(int)(x+0.9999999999999997);

让我们举个例子。
如果你甚至改变机器的位数,你改变到64位,机器的精度增加了,你的公式将停止工作,因为机器的精度将远远高于你在错误中的设置。

恕我直言。

P.S.可能还有其他选择,你的公式会在一个数字范围内失败。不断调整错误,从切换到不同的机器,或编译器的变化,你没有被告知,或当你改变机器中的数字表示,或从削减一个小数部分 的数字时,编译一个新版本的终端...你不知道什么会发生变化,我不认为做一个IF或者苦苦猜测会发生什么,一遍又一遍地写错误是个好主意......

我想这是值得思考的问题。

 
Andrey Kisselyov:

...

P.S. 根据定义,双倍数不能是整数,数字在机器内存中的表示不会改变。

也许你是说double不是一个整数数据类型,而不是说你不能在double类型 的变量中存储一个整数值的数字?一个整数倍可以是一个整数。

 

找到了关于计算机中实现的四舍五入和简单的堆栈后截断之间的区别的简单解释。十四岁,http://delphimaster.net/view/14-10885/all。

Tolik(2003-08-13 11:04)[11].

这种四舍五入的做法在会计上是被接受的。因此,税务局也采用这种四舍五入的方法,所以一切都应该加起来,至少在纸面上是这样:)



DiamondShark(2003-08-13 11:20)[12]

哦,哦,哦...再一次。
假设我们有一个接近于均匀随机的数字分布。然后通过 "算术 "四舍五入,我们有。

数字 不确定性
0 0
1 -1
2 -2
3 -3
4 -4
5 +5
6 +4
7 +3
8 +2
9 +1

很容易看出,如果有一大串数字需要加起来(文件项目的总数、账户余额等),那么 "算术 "四舍五入将积累一个系统误差,预计
0.5*10^N * 0.1 * N
其中。
n -- 进行四舍五入的数字的十进制权重(对两位数n=-2,对整数n=0,等等)。
0.1是每个数字的概率
N是一个数组中的整数数量

为了均衡误差概率,有必要对唯一未补偿的(见上表)误差+5进行补偿。这是通过人为地将其分割成两个同样可能的+5-5,这取决于前一个数字的奇偶性。

顺便说一下,在FPU状态字中有一个复选框,它控制着四舍五入模式(算术/会计)。


结束语。

另一个,http://delphimaster.net/view/15-1340952214/all:"因为普通用户(经理/会计)无法解释为什么四舍五入12.5和13.5--得到不同的结果。"


当给用户提供四舍五入函数的 "加速 "版本时,必须强烈警告,它们会在加法时产生更大的误差。这种错误必须在非常不同的情况下进行仔细评估。这很危险,充满了错误的积累。我很难想出一个例子,四舍五入是如此重要,以至于你可以忘记它所积累的误差。

Округление чисел. Неужели ТАК правильно???
  • delphimaster.net
3-10545           Kati                  2003-08-12 10:13  2003.09.04   обновление SQL запроса 14-10898          kalishenko            2003-08-14 20:09  2003.09.04   Win2000 Server и доступ в Интернет 1-10692           lww                   2003-08-20 10:30  2003.09.04   Как написать dll для 1С? 1-10813           koks                  2003-08-20...
 

Andrey Kisselyov:
я говорю про вот это безобразие

y=(int)(x+0.9999999999999997);

好了,先生们,你们已经表达了你们的观点。我会专门为你改变天花板的功能。

y=ceil(x);  ->  y=(x-(int)x>0)?(int)x+1:(int)x;
или через дефайн:
#define _ceil(x) (x-(int)x>0)?(int)x+1:(int)x

这个变体比变体:y=(int)(x+0.99999999999997) 慢25-50% 但它是最大限度的正确,对负整数有效,比ceil(x)快3倍。

但我自己,作为一个普通人和失败者,我将使用带九的变体,因为我认为你所有的论点都很无聊,对我这个长期用汇编程序编程的人来说,因此知道编译后代码会发生什么,这太过分了--把检查放在你可以不做的地方。

 

正数和负数的一个变体。

#define _ceil(x) (x-(int)x>0)?(int)x+1:(int)x
#define _round(x) (x>0)?(int)(x+0.5):(int)(x-0.5)
#define _floor(x) (x>0)?(int)x:((int)x-x>0)?(int)x-1:(int)x
这似乎是对ceil(),round(),floor()的全面替代,它的速度优势是3-4倍。