我正在使用BigDecimal进行简单的乘法运算,并且在乘以零时我发现了一些奇怪的行为(在这个用例中乘以零是正确的).
基本数学告诉我,任何乘以零的数字都将等于零(参见:零产品属性和乘法属性)
但是,以下代码将始终失败并出现相同的错误:
assertEquals(new BigDecimal(0), new BigDecimal(22.3).multiply(new BigDecimal(0)));
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)java.lang.AssertionError: Expected :0 Actual :0E-48
这是BigDecimal的不准确,还是我在某处遗漏了数学的一些利基分支?
注意:在IntelliJ 11中运行的JDK 1.6.0_27
在对这个问题的跟进中,似乎有些数字根本不能用浮点表示,而是近似的.
如何存储浮点数?
是否有不同尺寸的通用标准?
如果我使用浮点,我需要注意什么样的问题?
它们是否是跨语言兼容的(即,我需要处理哪些转换才能通过TCP/IP将python程序中的浮点数发送到C程序)?
-亚当
我很好奇在财务数据的计算方面存在任何"舍入"标准.我最初的想法是仅在数据呈现给用户(表示层)时执行舍入.
如果"舍入"数据然后用于进一步计算,应该使用"圆形"数字还是"原始"数字?有人有建议吗?
请注意,我知道不同的舍入方法,即银行家舍入等.
我应该使用什么类来表示金钱以避免大多数舍入错误?
我应该使用Decimal还是简单的内置number?
Money我可以使用现有的支持货币转换的类吗?
我应该避免哪些陷阱?
python precision currency rounding-error arbitrary-precision
我DECIMAL从MySQL-Table中读取以格式存储的数据.我想对R内的那些数字进行计算.
我过去常常使用它们进行数字再现as.numeric(),但文档说:
numeric与double(和real)相同.
但是R中还有一个数据类型Decimal吗?(没有舍入错误的数据类型,...)
这里有一个舍入错误问题的简单示例:
numbersStrings = c("0.1", "0.9")
numbersNumeric = as.numeric(numbersStrings)
numbersMirror = c(numbersNumeric, 1-numbersNumeric)
str(numbersMirror)
numbersMirror
unique(numbersMirror) # has two times 0.1 ...
sprintf("%.25f", numbersMirror)
sprintf("%.25f", unique(numbersMirror)) # ... because there was a rounding error
Run Code Online (Sandbox Code Playgroud) 在C#里还有两位小数四舍五入策略的准确性任何差异MidpointRounding.ToEven和MidpointRounding.AwayFromZero?我的意思是两者都确保在四舍五入的数字中均匀分布,或者是一个舍入策略而不是表示与另一个相比的舍入数字?
因为PHP中的float数据类型不准确,并且MySQL中的FLOAT占用的空间比INT多(并且不准确),所以我总是将价格存储为INT,在存储之前乘以100,以确保我们精确到2位小数的精度.但是我认为PHP是行为不端的.示例代码:
echo "<pre>";
$price = "1.15";
echo "Price = ";
var_dump($price);
$price_corrected = $price*100;
echo "Corrected price = ";
var_dump($price_corrected);
$price_int = intval(floor($price_corrected));
echo "Integer price = ";
var_dump($price_int);
echo "</pre>";
Run Code Online (Sandbox Code Playgroud)
产量:
Price = string(4) "1.15"
Corrected price = float(115)
Integer price = int(114)
Run Code Online (Sandbox Code Playgroud)
我很惊讶.当最终结果低于预期值1时,我期待我的测试结果看起来更像:
Price = string(4) "1.15"
Corrected price = float(114.999999999)
Integer price = int(114)
Run Code Online (Sandbox Code Playgroud)
这将证明浮动类型的不准确性.但为什么楼(115)返回114?
我有一个生成元文件(EMF)的应用程序.它使用参考设备(也就是屏幕)来渲染这些元文件,因此元文件的DPI会根据运行代码的机器而改变.
假设我的代码打算创建一个8.5英寸x 11英寸的图元文件.使用我的开发工作站作为参考,我最终获得了一个EMF
好的,所以rclFrame告诉我EMF的大小应该是
对吧.使用这些信息,我们也可以确定我的显示器的物理DPI,如果我的数学是正确的:
凡是播放此图元文件 - 一个EMF到PDF转换,在"摘要"页上的Windows资源管理器等的EMF时,单击鼠标右键 - 似乎截断计算的DPI值,显示87的,而不是87.9231(甚至88会很好).
当播放元文件时,这会导致页面的物理大小为8.48 x 10.98 in(使用87 dpi)而不是8.5 in x 11 in(使用88 dpi).
感谢您的任何见解.
我在MVC 5应用程序上使用Code First方法使用Entity Framework 6.x. 在这种特殊情况下,我的模型(以及其他内容)包含两个名为Latitude和Longitude的属性:
[Required, Range(-90, +90)]
public decimal Latitude { get; set; }
[Required, Range(-180, +180)]
public decimal Longitude { get; set; }
Run Code Online (Sandbox Code Playgroud)
当我执行迁移时,我得到了类似的东西
CreateTable("ResProperty"), c => new {
:
Latitude = c.Decimal(nullable: false, precision: 10, scale: 8),
Longitude = c.Decimal(nullable: false, precision: 11, scale: 8),
:
})
... other stuff
Run Code Online (Sandbox Code Playgroud)
所以纬度和经度都有8 位十进制数字.前者有2个整数(最多90个),后者有3个整数(最多180个).
执行Update-Database命令后,我的表的列显示为:
Latitude decimal(10,8)
Longitude decimal(11,8)
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很好.现在在我看来,我有一个地图和Javascript代码,允许用户重新定位标记.这也很好.重新定位标记时,纬度和经度字段将填充更新的值,其中(Javascript)具有超过12个十进制数字.这与AFAIK无关,因为我的比例是8位小数.
按下提交按钮并调用Create或Edit POST方法后,我检查模型实例,并确认模型中传递给控制器的实际值是正确的,它们有足够的十进制数字(那些Javascript代码)地点).所以价值是正确的.
现在......问题在于执行db.SaveChanges()之后数据库得到更新 - 我已经确认已经发生了实际的写入/更新 - 但不知何故内部EF忽略了我的实际值并写入了截断的纬度/经度四舍五入到只有两位小数,所以我的纬度在数据库中显示为09.500000000所有其他十进制数字都归零,因为似乎已经进行了舍入.
// Prior to SaveChanges()
Latitude = 9.08521879
Longitude = -79.51658792 …Run Code Online (Sandbox Code Playgroud) rounding-error decimal geospatial ef-code-first entity-framework-6
我在基于UNIX的系统上遇到问题sprintf没有正确地舍入值.
例如
double tmp = 88888888888885.875
char out[512];
Run Code Online (Sandbox Code Playgroud)
这是88,888,888,888,885.875只是为了让眼睛更容易.我给出了这样一个特别而又大的例子,因为它似乎在较小的数字上工作正常.
我试图以下面的方式使用它
sprintf(out, "%021.2f", tmp);
printf("out = %s\n", tmp);
Run Code Online (Sandbox Code Playgroud)
在Windows上,这会导致:
out = 000088888888888885.88
Run Code Online (Sandbox Code Playgroud)
例如AIX,但在Linux中也显示:
out = 000088888888888885.87
Run Code Online (Sandbox Code Playgroud)
为什么会这样?任何想法以及如何使它在Win/Unix上的行为方式相同
谢谢