11 个解决方案
#1
你的方法只能表示实数,类似pi sqrt(2) 之类的有理数呢。
最好是全部用符号运算,而不是数值运算。
最好是全部用符号运算,而不是数值运算。
#2
那再请教一下,对于精度丢失大家一般是怎么解决的?
#3
你想要多高的精度?
#4
要彻底解决精度问题,需要用符号运算。
要减小精度损失,我们有一系列数值计算方式来实现。
#5
你想要多高的精度?
刚才百度了一下符号运算,大致有了一个印象,貌似其实就是代数,想再请教一下大神,如果在解方程的过程中出现了精度丢失怎么办?
#6
你的方法只能表示实数,类似pi sqrt(2) 之类的有理数呢。
最好是全部用符号运算,而不是数值运算。
那再请教一下,对于精度丢失大家一般是怎么解决的?
要彻底解决精度问题,需要用符号运算。
要减小精度损失,我们有一系列数值计算方式来实现。
刚才百度了一下符号运算,大致有了一个印象,貌似其实就是代数,想再请教一下大神,如果在解方程的过程中出现了精度丢失怎么办?
#7
你用decimal试试呢?只要浮点型运算,精度丢失就不可避免的。
只能说decimal比double更靠谱一点。
只能说decimal比double更靠谱一点。
#8
用decimal可以减小出现误差的概率和误差量,因为decimal也是浮点型所以不可避免会出现误差。
根本原因在于计算机本身就是2进制的,对于浮点数计算机将小数点前面的数字进行除2取余数,小数点后面是成2取整数,对于乘法基本上只有末尾是0和5才可能最终得到没有小数的整数。
举例:
我们按照乘以 2 取整数位的方法,把 0.1 表示为二进制:
(1) 0.1 x 2 = 0.2 取整数位 0 得 0.0
(2) 0.2 x 2 = 0.4 取整数位 0 得 0.00
(3) 0.4 x 2 = 0.8 取整数位 0 得 0.000
(4) 0.8 x 2 = 1.6 取整数位 1 得 0.0001
(5) 0.6 x 2 = 0.2 取整数位 1 得 0.00011
(6) 0.2 x 2 = 0.4 取整数位 0 得 0.000110
(7) 0.4 x 2 = 0.8 取整数位 0 得 0.0001100
(8) 0.8 x 2 = 1.6 取整数位 1 得 0.00011001
(9) 0.6 x 2 = 1.2 取整数位 1 得 0.000110011
(n) ...
我们得到一个无限循环的二进制小数 0.000110011…
根本原因在于计算机本身就是2进制的,对于浮点数计算机将小数点前面的数字进行除2取余数,小数点后面是成2取整数,对于乘法基本上只有末尾是0和5才可能最终得到没有小数的整数。
举例:
我们按照乘以 2 取整数位的方法,把 0.1 表示为二进制:
(1) 0.1 x 2 = 0.2 取整数位 0 得 0.0
(2) 0.2 x 2 = 0.4 取整数位 0 得 0.00
(3) 0.4 x 2 = 0.8 取整数位 0 得 0.000
(4) 0.8 x 2 = 1.6 取整数位 1 得 0.0001
(5) 0.6 x 2 = 0.2 取整数位 1 得 0.00011
(6) 0.2 x 2 = 0.4 取整数位 0 得 0.000110
(7) 0.4 x 2 = 0.8 取整数位 0 得 0.0001100
(8) 0.8 x 2 = 1.6 取整数位 1 得 0.00011001
(9) 0.6 x 2 = 1.2 取整数位 1 得 0.000110011
(n) ...
我们得到一个无限循环的二进制小数 0.000110011…
#9
关于精度丢失实际上通用的做法是保留n位结果小数就用long把原始数据乘以10的n+2次方,然后用long计算
#10
建议用一个结构体表示,一个表示精度位,例如小数点三位,该数为-3,一个表示乘以小数点后位数的十次方的整数。例如1.234表示为 {3,1234}
#11
看是什么精度
如果是定点小数,可以直接用整数、长整型存储小数,然后程序里约定一个放大系数,这样进行四则运算时都不会损失精度
如果你的小数值是两数相除得到的,楼主的办法虽然可以解决存储问题,但是如果涉及到两个小数相加,损失精度依然是必然的
如果值是开方、自然对数、圆周率之类的,就更没办法了
归根结底,因为一个有限小数转换为二进制时,可能变成一个无限小数,但计算机里不可能存无限长度的数,所以丢失精度是必然的
从另一个角度看,整数之所以没有精度问题,是因为整数本身就是离散的,“整数1和整数100之间有多少个整数?”,这个数量是有限的;而小数是连续的数值,“小数1.1和1.2之间有多少个小数?”,答案是无限多个小数。而计算机里只能存储离散的量,所以你要存储的数值不幸处于它能表示的两个离散值之间时,精度丢失就是必然的。
如果是定点小数,可以直接用整数、长整型存储小数,然后程序里约定一个放大系数,这样进行四则运算时都不会损失精度
如果你的小数值是两数相除得到的,楼主的办法虽然可以解决存储问题,但是如果涉及到两个小数相加,损失精度依然是必然的
如果值是开方、自然对数、圆周率之类的,就更没办法了
归根结底,因为一个有限小数转换为二进制时,可能变成一个无限小数,但计算机里不可能存无限长度的数,所以丢失精度是必然的
从另一个角度看,整数之所以没有精度问题,是因为整数本身就是离散的,“整数1和整数100之间有多少个整数?”,这个数量是有限的;而小数是连续的数值,“小数1.1和1.2之间有多少个小数?”,答案是无限多个小数。而计算机里只能存储离散的量,所以你要存储的数值不幸处于它能表示的两个离散值之间时,精度丢失就是必然的。
#1
你的方法只能表示实数,类似pi sqrt(2) 之类的有理数呢。
最好是全部用符号运算,而不是数值运算。
最好是全部用符号运算,而不是数值运算。
#2
你的方法只能表示实数,类似pi sqrt(2) 之类的有理数呢。
最好是全部用符号运算,而不是数值运算。
那再请教一下,对于精度丢失大家一般是怎么解决的?
#3
你想要多高的精度?
#4
你的方法只能表示实数,类似pi sqrt(2) 之类的有理数呢。
最好是全部用符号运算,而不是数值运算。
那再请教一下,对于精度丢失大家一般是怎么解决的?
要彻底解决精度问题,需要用符号运算。
要减小精度损失,我们有一系列数值计算方式来实现。
#5
你想要多高的精度?
刚才百度了一下符号运算,大致有了一个印象,貌似其实就是代数,想再请教一下大神,如果在解方程的过程中出现了精度丢失怎么办?
#6
你的方法只能表示实数,类似pi sqrt(2) 之类的有理数呢。
最好是全部用符号运算,而不是数值运算。
那再请教一下,对于精度丢失大家一般是怎么解决的?
要彻底解决精度问题,需要用符号运算。
要减小精度损失,我们有一系列数值计算方式来实现。
刚才百度了一下符号运算,大致有了一个印象,貌似其实就是代数,想再请教一下大神,如果在解方程的过程中出现了精度丢失怎么办?
#7
你用decimal试试呢?只要浮点型运算,精度丢失就不可避免的。
只能说decimal比double更靠谱一点。
只能说decimal比double更靠谱一点。
#8
用decimal可以减小出现误差的概率和误差量,因为decimal也是浮点型所以不可避免会出现误差。
根本原因在于计算机本身就是2进制的,对于浮点数计算机将小数点前面的数字进行除2取余数,小数点后面是成2取整数,对于乘法基本上只有末尾是0和5才可能最终得到没有小数的整数。
举例:
我们按照乘以 2 取整数位的方法,把 0.1 表示为二进制:
(1) 0.1 x 2 = 0.2 取整数位 0 得 0.0
(2) 0.2 x 2 = 0.4 取整数位 0 得 0.00
(3) 0.4 x 2 = 0.8 取整数位 0 得 0.000
(4) 0.8 x 2 = 1.6 取整数位 1 得 0.0001
(5) 0.6 x 2 = 0.2 取整数位 1 得 0.00011
(6) 0.2 x 2 = 0.4 取整数位 0 得 0.000110
(7) 0.4 x 2 = 0.8 取整数位 0 得 0.0001100
(8) 0.8 x 2 = 1.6 取整数位 1 得 0.00011001
(9) 0.6 x 2 = 1.2 取整数位 1 得 0.000110011
(n) ...
我们得到一个无限循环的二进制小数 0.000110011…
根本原因在于计算机本身就是2进制的,对于浮点数计算机将小数点前面的数字进行除2取余数,小数点后面是成2取整数,对于乘法基本上只有末尾是0和5才可能最终得到没有小数的整数。
举例:
我们按照乘以 2 取整数位的方法,把 0.1 表示为二进制:
(1) 0.1 x 2 = 0.2 取整数位 0 得 0.0
(2) 0.2 x 2 = 0.4 取整数位 0 得 0.00
(3) 0.4 x 2 = 0.8 取整数位 0 得 0.000
(4) 0.8 x 2 = 1.6 取整数位 1 得 0.0001
(5) 0.6 x 2 = 0.2 取整数位 1 得 0.00011
(6) 0.2 x 2 = 0.4 取整数位 0 得 0.000110
(7) 0.4 x 2 = 0.8 取整数位 0 得 0.0001100
(8) 0.8 x 2 = 1.6 取整数位 1 得 0.00011001
(9) 0.6 x 2 = 1.2 取整数位 1 得 0.000110011
(n) ...
我们得到一个无限循环的二进制小数 0.000110011…
#9
关于精度丢失实际上通用的做法是保留n位结果小数就用long把原始数据乘以10的n+2次方,然后用long计算
#10
建议用一个结构体表示,一个表示精度位,例如小数点三位,该数为-3,一个表示乘以小数点后位数的十次方的整数。例如1.234表示为 {3,1234}
#11
看是什么精度
如果是定点小数,可以直接用整数、长整型存储小数,然后程序里约定一个放大系数,这样进行四则运算时都不会损失精度
如果你的小数值是两数相除得到的,楼主的办法虽然可以解决存储问题,但是如果涉及到两个小数相加,损失精度依然是必然的
如果值是开方、自然对数、圆周率之类的,就更没办法了
归根结底,因为一个有限小数转换为二进制时,可能变成一个无限小数,但计算机里不可能存无限长度的数,所以丢失精度是必然的
从另一个角度看,整数之所以没有精度问题,是因为整数本身就是离散的,“整数1和整数100之间有多少个整数?”,这个数量是有限的;而小数是连续的数值,“小数1.1和1.2之间有多少个小数?”,答案是无限多个小数。而计算机里只能存储离散的量,所以你要存储的数值不幸处于它能表示的两个离散值之间时,精度丢失就是必然的。
如果是定点小数,可以直接用整数、长整型存储小数,然后程序里约定一个放大系数,这样进行四则运算时都不会损失精度
如果你的小数值是两数相除得到的,楼主的办法虽然可以解决存储问题,但是如果涉及到两个小数相加,损失精度依然是必然的
如果值是开方、自然对数、圆周率之类的,就更没办法了
归根结底,因为一个有限小数转换为二进制时,可能变成一个无限小数,但计算机里不可能存无限长度的数,所以丢失精度是必然的
从另一个角度看,整数之所以没有精度问题,是因为整数本身就是离散的,“整数1和整数100之间有多少个整数?”,这个数量是有限的;而小数是连续的数值,“小数1.1和1.2之间有多少个小数?”,答案是无限多个小数。而计算机里只能存储离散的量,所以你要存储的数值不幸处于它能表示的两个离散值之间时,精度丢失就是必然的。