跳转至

数据精确度

二进制科学记数法

二进制科学记数法(Binary Scientific Notation)是一种表示二进制小数的方法。二进制科学记数法通常用于计算机科学中,特别是在处理浮点数时。

在二进制科学记数法中,一个数被表示为一个尾数(Mantissa)一个指数(Exponent)。尾数是二进制小数,指数是用来表示尾数应移动的位数和方向。

例如,二进制数 1101.101 可以表示为 1.101101 x 2^3。在这个例子中,尾数是 1.101101,指数是 3。这表示尾数需要向左移动3位,得到原来的数 1101.101。

在计算机中,浮点数的表示通常使用一种特殊的二进制科学记数法,称为 IEEE 754 标准。在这个标准中,一个浮点数被分为三个部分:符号位(Sign),指数(Exponent)和尾数(Mantissa 或 Fraction)。这个标准定义了如何表示、计算和舍入浮点数,以及处理特殊的值,如无穷大、无穷小和非数字(NaN)。

浮点数用二进制科学计数法表示的,不能精确的表示十进制0.1、0.01,进行计算时可能会有舍入。需要用DecimalNumber保证算术运算时精确的结果。

处理数据精度问题,接口返回的是Number类型,属性也得用NSNumber类型接收,value的值是正确的。

- (void)setValue:(id)value forKey:(NSString *)key {
    [super setValue:value forKey:key];
    if ([value isKindOfClass:[NSNumber class]]) {
        //获取类中的某个属性
        objc_property_t property = class_getProperty(object_getClass(self), key.UTF8String);
        //接口返回的字段比较多,模型里可能没有写,防空判断
        if (property) {
            //获取属性的信息:用什么修饰的
            const char *cType = property_getAttributes(property);
            NSString *typeStr = [NSString stringWithCString:cType encoding:NSUTF8StringEncoding];
            NSLog(@"type = %@",typeStr);
            if ([typeStr hasPrefix:@"T@\"NSNumber\""]) {
                //属性是NSNumber类型,调用setter方法
                //首字母大写
                NSString *firstString = [[key substringToIndex:1] uppercaseString];
                key =  [key stringByReplacingCharactersInRange:NSMakeRange(0, 1) withString:firstString];
                SEL sel = NSSelectorFromString([NSString stringWithFormat:@"set%@:",key]);
                if (sel) {
                    ((void(*)(id,SEL,id))objc_msgSend)(self,sel,value);
                }
            }
        }
    }
}