运行时将String转换为float存入Realm数据库出现精度丢失如何解决?
问题原因
这一问题本质是float单精度浮点数本身的特性导致的,和Realm数据库无关:二进制浮点数的编码规则无法精确表示绝大多数十进制小数,float的有效精度只有6~7位,类似1.31这类十进制小数转float后天然就会出现1.3099999...的精度误差。
解决方案
最优方案:直接存储字符串版本号
版本号本身不属于需要做数值运算的业务字段,且后续很可能出现1.31.1这类多段式版本号,完全不适合用浮点类型存储。
直接将Realm模型中的appVersion字段改为String类型,无需做类型转换,直接写入原始值即可:
managedMetadata.setAppVersion(BuildConfig.VERSION_NAME);
该方案完全避免精度问题,无需额外处理,适配所有版本号格式。
方案二:需要数值比较时改用高精度存储
如果业务逻辑必须用数值类型做版本大小比对,可以选择以下两种实现:
- 改用
BigDecimal转Double存储:Double双精度浮点数的有效精度可达15~16位,对于版本号这类小数位数少的场景完全足够,代码示例:
double appVersion = new BigDecimal(BuildConfig.VERSION_NAME).doubleValue(); managedMetadata.setAppVersion(appVersion);
需要同步将Realm中的appVersion字段改为Double类型。
- 缩放为整数存储:提前约定版本号的小数位数,比如默认保留2位小数,将版本号放大100倍转为Long类型存储,完全不存在精度损失:
// 写入数据 BigDecimal versionDec = new BigDecimal(BuildConfig.VERSION_NAME); long appVersionVal = versionDec.multiply(new BigDecimal(100)).longValueExact(); managedMetadata.setAppVersion(appVersionVal); // 读取后转换为显示用的字符串 String displayVersion = new BigDecimal(appVersionVal).divide(new BigDecimal(100)).toString();
内容的提问来源于stack exchange,提问作者codewithbawo
相关产品推荐
相关产品推荐

