美文网首页
iOS端浮点数精度处理

iOS端浮点数精度处理

作者: Coder_Messi | 来源:发表于2020-11-19 11:30 被阅读0次

做这么久coder了,才碰到了客户端与服务端传递浮点数的问题,说起来有点惭愧。
场景是这样的:
服务端需要我这边上传一个1位小数位的浮点数,比如@0.6这样,我直接就这样放到字典里传过去,到服务端拿到的变成了0.59999999993或者0.6000000007,出现了精度丢失。我很纳闷,在我这边的log里显示的明明是0.6,开始以为是服务端做了哪些处理,服务端说他们是直接拿到数据就入库,没有别的操作,并且Android那边传的就没问题。我只能一步步调试自己的代码,最终发现问题出现在这一步:NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:nil];,就是字典序列化为二进制数据时,浮点数精度出现了丢失,然后我以为是options这个参数的问题,就试了所有的选项

typedef NS_OPTIONS(NSUInteger, NSJSONWritingOptions) {
    NSJSONWritingPrettyPrinted = (1UL << 0),

    /* Sorts dictionary keys for output using [NSLocale systemLocale]. Keys are compared using NSNumericSearch. The specific sorting method used is subject to change.
     */
    NSJSONWritingSortedKeys API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) = (1UL << 1),
    NSJSONWritingFragmentsAllowed = (1UL << 2),
    NSJSONWritingWithoutEscapingSlashes API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) = (1UL << 3),
} API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0));

结果不如我所愿,不是参数的问题,用以上那些option结果一样。
经过一番查找,发现有NSDecimalNumber这样一个处理浮点数的类,继承自NSNumber,有这么几个api可以用:

- (instancetype)initWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
- (instancetype)initWithDecimal:(NSDecimal)dcm NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithString:(nullable NSString *)numberValue;
- (instancetype)initWithString:(nullable NSString *)numberValue locale:(nullable id)locale;

- (NSString *)descriptionWithLocale:(nullable id)locale;

+ (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa exponent:(short)exponent isNegative:(BOOL)flag;
+ (NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)dcm;
+ (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue;
+ (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue locale:(nullable id)locale;

网上有很多关于这个类的用法,很多还挺复杂,我直接用这个类方法

+ (NSDecimalNumber *)decimalNumberWithString:(nullable NSString *)numberValue;

搞定。
至于为什么会出现这样的问题,经过跟公司的一个大牛探讨,说是浮点数会有一个上下浮动的微小区间,用浮点数转换时变成这个区间的任何一个数都是正常的,计算机就是这么处理的。PS:大牛还大骂设计这个接口的人不专业,有涉及到浮点数精度问题时不要用double类型,转换成int处理会更好。

相关文章

  • iOS端浮点数精度处理

    做这么久coder了,才碰到了客户端与服务端传递浮点数的问题,说起来有点惭愧。场景是这样的:服务端需要我这边上传一...

  • py_28 Decimal处理小数计算精度问题

    python Decimal这个类处理浮点数精度 浮点数在内存中存储的时候因为存储机制的原因,天然存在精度丢失的现...

  • iOS数据模型化时浮点数精度丢失

    iOS数据模型化时当json中有浮点数时,会出现浮点数精度丢失的问题如:@"{"number":"22.5"}"转...

  • [Java] BigDecimal的使用

    BigDecimal BigDecimal位于java.math.BigDecimal包,用于处理浮点数高精度运算...

  • iOS关于浮点数精度处理问题

    场景: 在一个提款场景中,当用户点击提取所有的资金后,由于从后台传过来的值是例如:100.59999999,而我们...

  • iOS浮点数精度问题

    前言 浮点数是无法精确表示大部分实数的 单精度浮点数和双精度浮点数 单精度(float),一般在计算机中存储占用4...

  • 浮点数

    双精度浮点数类型 double单精度浮点数类型 float 以上两种都使用 浮点数 来表示小数 : 与之相对的是 ...

  • iOS 浮点数精度问题

    浮点的加减乘除运算,最好转成NSDecimalNumber 来进行; 通过decimalNumberByRound...

  • iOS 浮点数精度丢失

    后台返回的浮点类型的数据为 9.37,但是在使用浮点显示的时候就会变成 9.369999999999999 这种样...

  • awk实战6-awk浮点数精度的坑

    awk在处理浮点数加减时默认是按double-float来处理,一般的处理对精度要求没有那么高,因此通常用awk不...

网友评论

      本文标题:iOS端浮点数精度处理

      本文链接:https://www.haomeiwen.com/subject/yfixiktx.html