数据精确度¶
二进制科学记数法¶
二进制科学记数法(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);
}
}
}
}
}