将价格存储为双精度浮点数?

5

在C++中,将价格存储在双精度变量中是否安全?在C#和Java中,您可以使用Decimal。(他们还说在双精度变量中存储价格是非常糟糕的想法)。那么在C++中应该怎么做呢?


浮点数怎么样?为什么不是一个好主意? - Alejandro Alcalde
小数部分需要多少位小数?它是可变的还是固定的? - amdn
请看以下与编程有关的内容:https://dev59.com/TGYq5IYBdhLWcg3w7EwF - stijn
2
因为除非你正在处理会计系统并且需要进行多个百分比乘法运算,否则使用Double类型是过度的,上次这肯定是个坏主意。但随着时间的推移,对于大多数计算机系统来说,Double类型已经不再是问题了。 - PicoCreator
相关阅读请参考此文献:http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2849.pdf - Casper Beyer
7个回答

5
如果价格范围合适(很可能是),您可以在最后两位数字前使用隐含点的long long。因此,12000 将意味着 120.00。这被称为“定点”算术。但是您需要注意两个货币值的乘法(反正为什么需要呢)。

不,将两种货币相乘会得到错误的结果:100*100=10000。现在你需要小数点后四位数字。但我理解这是一个罕见的情况。大多数时候,您只需将货币与无单位数量相乘即可。 - cyco130

2

您可以使用 long double 存储价格。

// get_money manipulator example
#include <iostream>     // std::cin, std::cout
#include <iomanip>      // std::get_money

int main ()
{
  long double price;
  std::cout << "Please, enter the price: ";
  std::cin >> std::get_money(price);

  if (std::cin.fail()) std::cout << "Error reading price\n";
  else std::cout << "The price entered is: " << price << '\n';

  return 0;
}

2

2
很遗憾,您在C++中和其他地方一样都会遇到相同的问题。虽然它比float好得多,但您不能相信double可以正确存储值。
在C++中没有像Decimal这样的数据结构可用,因此您需要寻找一个可以为您完成此操作的库,或者使用另一种格式。
一个简单的解决方案是将值“42.37”存储为“4237”-这是您可以信任的方式。但是,如果您正在使用这些数字进行计算,则仍建议使用double。
如果您决定使用更大的变量类型,如long double,则可以减少出现问题的可能性-但这并不能保证完全正确。

2

我建议你使用intunsigned int来以最小的货币单位存储价格。例如,如果一件商品售价为5.99美元,并且你不需要跟踪小于一分钱的价值,请将其存储在int中,即599


1
根据您所需的精度而定。如果您要处理像 5.259.14 等数字,您甚至不需要使用 doublefloat 就足够了。
如果您要处理帐户余额,并向类似 18 570.548911545 的数字加上 0.01%,那么 double 提供的 15 位小数的精度就足够了。
如果您需要略高的精度,请选择 long double。如果还不够,才考虑寻找“更精确的替代方案”。

1
问题在于,浮点数和双精度浮点数无法精确存储所有小数。如果您尝试存储“0.1十进制”,它会变成“0.0001100110011001100110...二进制”。如果您将其转换回来,它是“0.09999...十进制”。当您使用这些数字进行计算时,这可能会导致问题。使用更大的数据类型可以减少此类问题的可能性,但不能保证其正常工作。 - maja
@maja:是的,我很清楚小马。但即使有这个,四舍五入也可以。 - LihO

1

根据多年的ERP开发经验...

价格只能存储在整数(int, long, long int, int64等),其数量与隐含的小数位有关(例如将$4.00存储为400)。

举个例子,想象一下产品的价格变化。

  1. 1个单位售价1美元 --- 单价1美元
  2. 25个单位售价13.33美元 --- 每个单位的价格是0.393939393939无限循环。

将第2行的单价存储在double中会导致四舍五入。不要存储为double,而是用一个int变量表示价格1333和一个表示数量的变量25,每当需要显示单价时计算。

当以doublefloat等形式存储时,始终存在将十进制值转换为二进制值时出现舍入/精度损失的风险。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接