在我的课程中,我被告知:
连续值大约在内存中表示,因此使用浮点数计算涉及舍入误差.这些是位模式的微小差异; 因此,
e==f如果是漂浮物e,f则测试是不安全的.
参考Java.
这是真的?我使用了doubles和floats的比较语句,并且从未遇到过舍入问题.从来没有我在课本上读过类似的东西.当然虚拟机占了这个?
我一直在胡扯如何处理PHP中的货币显示和数学,并且很长一段时间以来一直使用该DECIMAL类型将其存储在MySQL中,并使用money_format()格式化它以在网页上显示.但是,今天我看了一下实际的原型:
string money_format ( string $format , float $number )
Run Code Online (Sandbox Code Playgroud)
我现在有点困惑.所有我被告知的是,避免浮动钱!但这里是基本的格式化函数(比如快五倍),将输入转换为浮点数.number_format()做同样的事.
所以我的问题是:
除非我处理的是分数美分或数万亿美元(而且我都没有处理过),我是否应该关注显示和存储(但从不进行数学计算)货币被抛到浮点数?我是否会接近浮动点不准确的区域改变我的数字?
如果对#1的回答是我确实应该关注,那么为什么这样money_format()构建呢?
免责声明:截至2011年10月14日,为了清晰起见,完全重写
鉴于number JavaScript中的原语是IEEE 754 64位浮点(在其他语言中称为双精度),并使用浮点数来模拟货币是一个坏主意,是Money原型(JavaScript)或Coffeescript类,可以简化使用伪整数美分和字符串货币ISO 4217代码表示可用的货币?
^还有更好的方式来表达这一点.
我希望找到能够反映其他许多语言的常见设计模式的东西,其中包括整数原语.
作为示例,我熟悉ruby 的money gem和python-money包,它们都实现了这种设计模式的变体.
理想情况下寻找能与backbone.js和node.js配合使用的东西,但所有建议都值得赞赏.
编辑4:据我所知,只要roundDownOrUp ? floor : ceiling在每次操作后调用Number的实现(&在链接操作之间),一切都会像处理整数那样起作用.
我读过如何在JavaScript中将数字格式化为金钱? 在那里我找到了accounting.js和jQuery Globalize,它们都做了漂亮的打印但不是为了模拟货币并用它们执行操作.
编辑1:刚刚在npm注册表中找到了知道ISO 4217的JSorm货币,但似乎没有包含浮动" 陷阱 "的任何修复.如果我有误读,请更正.
编辑2折叠成重写.
编辑3:看起来好的选择是使用@RicardoTomasi建议的node-bigint.
例如,对于原始,我会这样做
if ( (x >= 6000) && (x <= 20000) )
// do something here
Run Code Online (Sandbox Code Playgroud)
并且使用NSDecimalNumber,这就是我所拥有的
if ( (([x compare:[NSNumber numberWithInt:6000]] == NSOrderedSame) ||
([x compare:[NSNumber numberWithInt:6000]] == NSOrderedDescending))
&& (([x compare:[NSNumber numberWithInt:20000]] == NSOrderedSame) ||
([x compare:[NSNumber numberWithInt:6000]] == NSOrderedAscending)) )
{
// do something here
}
Run Code Online (Sandbox Code Playgroud)
这种比较还有其他方法(更简单,更优雅)吗?如果我将值转换为原始,我使用什么原语?我不想使用CGFloat,float或double,因为我在这里处理货币.或者如果我将它们转换为上面提到的那些,有人可以验证/解释精度吗?
TL; DR 1用C表示货币或货币的准确且可维护的方法是什么?
问题的背景:
许多其他语言已经回答了这个问题,但我找不到C语言的可靠答案.
Objective-C 如何在Objective-C/iOS中代表钱?
注意:对于其他语言,还有更多类似的问题,我只是为了代表性目的而提出了一些问题.
所有这些问题都可以提炼为"使用decimal数据类型",其中特定类型可能因语言而异.
有一个相关的问题最终建议使用"定点"方法,但没有一个答案使用C中的特定数据类型.
同样,我已经查看过任意精度库,例如GMP,但我不清楚这是否是最好的使用方法.
简化假设:
假设基于x86或x64的架构,但请调出任何可能影响基于RISC的架构(如Power芯片或Arm芯片)的假设.
计算的准确性是主要要求. 易于维护将是下一个要求.计算速度很重要,但与其他要求相比是三级的.
计算需要能够安全地支持对轧机精确的操作以及高达数万亿的支撑值(10 ^ 9)
与其他问题的区别:
如上所述,此类问题之前已被问过多种其他语言.由于几个原因,这个问题与其他问题不同.
使用接受的答案:为什么不使用Double或Float来表示货币?,让我们强调差异.
(解决方案1)几乎可以使用任何语言的解决方案是使用整数,并计算分数.例如,1025将是10.25美元.几种语言也有内置类型来处理钱.(解决方案2)其中,Java具有BigDecimal类,C#具有十进制类型.
重点强调了两个建议的解决方案
第一种解决方案基本上是"定点"方法的变体.该解决方案存在一个问题,即建议的范围(跟踪分数)不足以进行基于轧机的计算,并且在舍入时将丢失重要信息.
另一种解决方案是使用decimalC中不可用的本机类.
同样,答案不考虑其他选项,例如创建用于处理这些计算的结构或使用任意精度库.这些是可以理解的差异,因为Java没有结构,为什么在语言中有本机支持时考虑第三方库.
此问题与该问题和其他相关问题不同,因为C不具有相同级别的本机类型支持,并且具有其他语言不支持的语言功能.我还没有看到任何其他问题解决在C中可以采用的多种方式.
问题:
根据我的研究,float由于浮点错误,似乎不适合用于在C程序中表示货币的数据类型.
我应该用什么来代表C中的钱,为什么这种方法比其他方法更好?
1 此问题以较短的形式开始,但收到的反馈意见表明需要澄清问题.
为什么应用程序通常不使用整数数据类型(例如int或long在C++/Java/C#中)来在内部表示货币值,而不是使用浮点数据类型(float,double)或类似Java的BigDecimal?
例如,如果我正在编写Java应用程序并且我有一个变量,我想用美元表示实际值(不需要代表几分钱),我可以声明一个代表分数的int值.例如,值"$ 1.00"将表示为100.这似乎是使用a的好方法double(请参阅问题为什么不使用Double或Float来表示货币?)或a BigDecimal(这是一个比简单更重量级的对象)原始的int).
显然,在将值显示给用户之前,或者在用户输入货币值之前,整数值需要"翻译"(即从100到"1美元"或"1.00美元"),但这样做似乎并不显着比格式化double或BigDecimal显示更麻烦.
为什么这种方法在不需要代表分数(或其他货币类型的等价物)的应用程序中不是最佳实践?
可能重复:
为什么不使用Double或Float来表示货币?
我正在为我的高中课程编写一个基本的Java命令行程序.我们现在只处理变量.它用于计算购买后更改中任何类型的账单和硬币数量.这是我的计划:
class Assign2c {
public static void main(String[] args) {
double cost = 10.990;
int paid = 20;
double change = paid - cost;
int five, toonie, loonies, quarter, dime, nickel, penny;
five = (int)(change / 5.0);
change -= five * 5.0;
toonie = (int)(change / 2.0);
change -= toonie * 2.0;
loonies = (int)change;
change -= loonies;
quarter = (int)(change / 0.25);
change -= quarter * 0.25;
dime = (int)(change / 0.1);
change -= dime * 0.1; …Run Code Online (Sandbox Code Playgroud) 我有一个场景,我把货币作为一个字符串,例如:
$ 199.00
R $ 399,00
£25.00
90,83€
AED 449.00
如何在java中将这些货币转换为双倍?
我有一些代码块:
float total = <some float>;
double some_dbl = <some double>;
total *= some_dbl;
Run Code Online (Sandbox Code Playgroud)
这引发了我想要关闭的编译器警告,但我不喜欢关闭这样的警告 - 相反,我宁愿根据需要显式地转换类型.让我思考的是...... (float)(total * some_dbl)比准确total * (float)some_dbl吗?它是编译器还是平台特定的?
更好的代码示例(链接如下):
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
int main() {
double d_total = 1.2345678;
float f_total = (float)d_total;
double some_dbl = 6.7809123;
double actual = (d_total * some_dbl);
float no_cast = (float)(f_total * some_dbl);
float with_cast = (float)(f_total * (float)some_dbl);
cout << "actual: " << setprecision(25) << actual << endl;
cout << …Run Code Online (Sandbox Code Playgroud) 在Java中,没有精确表示浮点运算.例如这个java代码:
float a = 1.2;
float b= 3.0;
float c = a * b;
if(c == 3.6){
System.out.println("c is 3.6");
}
else {
System.out.println("c is not 3.6");
}
Run Code Online (Sandbox Code Playgroud)
打印"c不是3.6".
我对超过3位小数的精度感兴趣(#.###).我如何处理这个问题来乘以浮点数并可靠地比较它们?
currency ×5
java ×4
backbone.js ×1
c ×1
c++ ×1
double ×1
ios ×1
javascript ×1
memory ×1
money-format ×1
node.js ×1
numbers ×1
objective-c ×1
php ×1
types ×1