我想找到一种有效的方法来确保小数位数 双倍不超过三个。
<plugin name="cordova-plugin-whitelist" source="npm" spec="~1.2.1" />
目前,我所做的只是使用正则表达式拆分和计数索引。如下。
double num1 = 10.012; //True
double num2 = 10.2211; //False
double num2 = 10.2; //True
有没有一种有效或更好的方法来做到这一点,因为我会打电话给你 功能很多?
答案 0 :(得分:2)
如果您想要一种能够以与将double
转换为字符串的最终结果一致的方式告诉您该信息的解决方案,那么效率并没有真正进入其中;你基本上必须转换为字符串并检查。结果是,对于double来说,完全有可能包含一个在数学上具有(比方说)十万分之一(例如)非零值的值,但是当转换为字符串时不会。这就是IEEE-754双精度二进制浮点的乐趣:从字符串表示中获得的位数只能是将值与其相邻可表示值区分开来的数量。来自the Double
docs:
m 或 a 的小数部分必须打印多少位数?必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只有多少,更多的数字才能唯一地将参数值与类型
double
的相邻值区分开来。也就是说,假设 x 是由此方法为有限非零参数 d 生成的十进制表示所表示的精确数学值。那么 d 必须是最接近 x 的double
值;或者如果两个double
值同样接近 x ,则 d 必须是其中之一,并且 d <的有效位的最低有效位/ em>必须是0
。
但是如果您不关心这一点,并且假设将您的价值范围限制为long
是可以的,那么您可以这样做:
private static boolean onlyThreePlaces(double v) {
double d = (double)((long)(v * 1000)) / 1000;
return d == v;
}
...应该比String
更少的内存开销 - 往返。
然而,如果该方法和Double.toString(double)
的结果在术语上不匹配,我会感到惊讶由于上面给出的原因,小数点后面的数字。
在对该问题的评论中,您已经说过(当我询问价值范围时):
老实说,我不确定。我处理价格;首先,我假设0-200K
将double
用于财务价值通常不是一个好主意。如果您因内存问题而不想使用BigDecimal
,请选择您的精确度,并根据您的值范围使用int
或long
。例如,如果你只需要一分钱的精确度,你就可以使用乘以100的值(例如,2000是Ⓠ20[或者你正在使用的任何货币,我使用Ⓠ来代替quatloos])。如果你需要精确到一分钱的thousanths(如你的问题所示),那么乘以100000(例如,2000000是Ⓠ20)。如果您需要更高的精度,请选择更大的乘数。即使你去了一分钱(muliplier:10000000)的100 thousanths,long
你的范围是Ⓠ-922,337,203,685到Ⓠ922,337,203,685。
这样做的另一个好处是可以让这项检查变得更容易:只需要%
。如果您的乘数是10000000(一分钱的十万分之一),那么只需value % 10000 != 0
来识别无效的乘数(或value % 10000 == 0
来识别有效的那些)。
long num1 = 100120000; // 10.012 => true
// 100120000 % 10000 is 0 = valid
long num2 = 102211000; // 10.2211 => false
// 102211000 % 10000 is 1000 = invalid
long num3 = 102000000; // 10.2 => true
// 102000000 % 10000 is 0 = valid