fmod(x,1)
似乎x
其中std::cout << fmod(min, 1) << "|" << fmod(max, 1) << std::endl;
是一个双给出错误的结果,作为行的输出:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
#include <math.h>
const int deviation = 3;
void weightedRandomNumber(double min, double max);
int main() {
srand(time(nullptr));
std::cout.precision(16);
std::cout << 123.1 << "|" << 2789.3234 << std::endl;
weightedRandomNumber(123.1, 2789.3234);
system("pause");
return 0;
}
void weightedRandomNumber(double min, double max) {//inclusive
int multiplier = 1;
std::cout << min << "|" << max << std::endl;
while (fmod(min, 1) > 0 || fmod(max, 1) > 0) {
std::cout << min << "|" << max << std::endl;
std::cout << fmod(min, 1) << "|" << fmod(max, 1) << std::endl;
min *= 10;
max *= 10;
multiplier++;
}
std::cout << min << "|" << max << std::endl;
std::cout << multiplier << std::endl;
}
我忘记了你所说的名字,但这是解释我问题所需的最少代码:
123.1|2789.3234
123.1|2789.3234
123.1|2789.3234
0.09999999999999432|0.3234000000002197
1231|27893.234
0|0.2340000000040163
12310|278932.34
0|0.3400000000256114
123100|2789323.4
0|0.400000000372529
1231000|27893234
0|3.725290298461914e-09
12310000|278932340.0000001
0|5.960464477539063e-08
123100000|2789323400
0|4.76837158203125e-07
1231000000|27893234000
0|3.814697265625e-06
12310000000|278932340000.0001
0|6.103515625e-05
123100000000|2789323400000
0|0.00048828125
1231000000000|27893234000000
0|0.00390625
12310000000000|278932340000000
0|0.03125
123100000000000|2789323400000001
0|0.5
1231000000000000|2.7893234e+16
14
运行代码时得到的输出是这样的:
C:\Users\Marius>H:\Liquibase\Liquibase \
--driver=com.microsoft.sqlserver.jdbc.SQLServerDriver \
--classpath="C:\\Program Files\\Microsoft JDBC Driver 6.2 for SQL Server\\sqljdbc_6.2\\enu\\mssql-jdbc-6.2.2.jre7.jar" \
--url="jdbc:sqlserver://localhost:3306; databaseName=Test" \
--changeLogFile="H:\Liquibase\dbchangelog.xml" \
--username=liquibase \
--password=liquibase \
Update
除此之外,我不知道该说些什么,如果我错过任何必要的话请发表评论,以便我可以修改我的问题。
答案 0 :(得分:1)
问题不在于fmod
,它可以提供最高精度的结果。问题是cout精度不像你期望的那样,加上“舍入”,因为double不能准确地存储0.1
来表示cout
认为16的精度。
此代码演示了此问题。当您将123.1
分配给double时,实际上会发生舍入,但是由于左边的3位数字在变为较小的数字之前是不可见的。
int main() {
std::cout.precision(16);
std::cout << (123.1L - 123L);
}
输出:
0.09999999999999432
实际上......这更简洁地说明了这个问题:
int main() {
std::cout.precision(20);
std::cout << 123.1;
}
123.09999999999999432
进一步阅读对您问题的评论: Is floating point math broken?
此外,对于绝大多数场景来说,双倍都不错。对于准确的,递归数学,你需要考虑一个重型数学库,甚至是数学专业语言。