在Objective-C中获取NSDecimalNumber的指数?
给定一个小数点,我怎样才能找到指数(标度) 虽然原则上可以先转换成NSString,然后再进行一些丑陋的字符串操作,但我宁愿避免这样做 使用Java BigDecimal,我可以调用该方法来获取比例 对于NSDecimalNumber是否存在类似的简洁方法?不,它看起来没有等效方法。我想你可能得自己写在Objective-C中获取NSDecimalNumber的指数?,objective-c,ios,Objective C,Ios,给定一个小数点,我怎样才能找到指数(标度) 虽然原则上可以先转换成NSString,然后再进行一些丑陋的字符串操作,但我宁愿避免这样做 使用Java BigDecimal,我可以调用该方法来获取比例 对于NSDecimalNumber是否存在类似的简洁方法?不,它看起来没有等效方法。我想你可能得自己写 但是,如果您不介意仔细研究一下(并忽略文档警告),您可以查看从中返回的-它有许多字段,您可以访问这些字段。主观上,这比NSString操作更好还是更差取决于您。如果出于某种原因确实需要指数(而不是
但是,如果您不介意仔细研究一下(并忽略文档警告),您可以查看从中返回的-它有许多字段,您可以访问这些字段。主观上,这比NSString操作更好还是更差取决于您。如果出于某种原因确实需要指数(而不是简单的显示,您可以配置数字格式化程序为您提供),您可以使用
-doubleValue
方法获得原语double,然后使用frexp(3)
获取尾数和指数值
用于执行和存储浮点数学的对象背后的整个设计是,您可以更有效地处理计算和精度错误,但是,该设计的限制是,一旦您从标量(如双精度
或尾数和指数的组合)转换,您应该保持在对象框架内,而不是转换回(可能)不太精确的格式
我建议使用-doubleValue
是最好的选择,因为其他答案建议访问可能会更改的私有结构记录,使用这些建议不会导致精度损失,而事实上,可能会有(如头文件中所述)。当转换为double时,您和使用/阅读您的代码的人确切地知道可能出现的精度错误,因为该类型已被很好地理解和记录
最后,如果您想确定转换是否会导致错误,可以创建并使用,它将为您提供有关转换为双标量类型时可能出现的舍入/精度错误类型的信息
我还建议您使用apple bug reporter添加增强请求,声明您希望直接访问指数,并可能添加更高精度的类型,如-longdouplevalue
方法
编辑包括更多信息您可以在
NSDecimal
上访问它:
int exponent = decimalNumber.decimalValue._exponent;
您可以将数字与尾数等于1的实例进行比较,从而更改指数。它可以像二进制搜索一样工作。如果您想让表达式处于base-10形式(frexp(3)似乎只执行base-2),可以尝试以下操作:
double mantissa = [someDecimalNumber doubleValue];
int exp = 0;
if (mantissa >= 1.0f) {
while (mantissa >= 1.0f) {
mantissa = mantissa / 10.0f;
exp++;
}
} else {
while (mantissa*10.0f < 1.0f) {
mantissa = mantissa * 10.0f;
exp--;
}
}
NSLog(@"%f = %f x 10^%d", [someDecimalNumber doubleValue], mantissa, exp);
double尾数=[someDecimalNumber doubleValue];
int exp=0;
如果(尾数>=1.0f){
而(尾数>=1.0f){
尾数=尾数/10.0f;
exp++;
}
}否则{
而(尾数*10.0f<1.0f){
尾数=尾数*10.0f;
经验--;
}
}
NSLog(@%f=%f x 10^%d,[someDecimalNumber doubleValue],尾数,exp);
再想一想,上面Jason Coco的回答中有一种记录在案的、不太复杂的方法可以做到这一点。为了完整起见,将其保留在此处,尽管这可能不是最佳选择:)将大十进制
转换为双精度
将破坏精度。错误的解决方案。@Sulthan不幸的是,这是目前框架提供的最好的解决方案。转换为NSDecimal
并读取私人记录(如其他答案中所建议的)不仅是完全错误的,而且如果查看标题中的注释,它会指定转换将以精确的方式进行(因此,转换为double的问题与此完全相同,但您欺骗了任何阅读您的代码的人——可能还有您自己——使其安全)。至少你知道转换为双精度类型时会出现什么问题。@jasoncoo当然,当NSDecimalNumber
包含float
或BOOL
时,将其转换为NSDecimal
将不准确。但精度损失的程度将不同于从NSDecimal>转换
转换为double
。这就像试图将double
转换为char
。我不为使用私人记录辩护,但这也不是一个解决方案。@Sulthan这绝对不像将double转换为char,因为你清楚地了解其中的原因。你也不知道会有什么潜在的精度损失将从NSDecimalNumber
转换为NSDecimalNumber
。避免字符串操作的唯一安全选项是使用double并使用数字处理程序来判断数字是否可以表示为double,如果不能,估计的精度损失是多少。如果没有,则需要进一步计算在数字上,损失可能是可以接受的。这不是你的决定,而是实现者的决定。除了“NSDecimal的字段是私有的。”——;这是私有API使用,苹果不太可能发现,但私有API使用仍然存在。(旁白:可能是因为有很多情况下,数字不会以标准化形式出现;例如,NSDecimalNumber
可能在某个时候使用了NSDecimalNormalize
,但不能保证它会撤销)更糟糕的是,不仅您访问的是专门记录为“不访问”的私人记录,而且转换为NSDecimal
可能会导致意想不到的副作用/精度错误,而转换为double
已知有特定的精度限制。请您联系告诉我们为什么需要知道指数?请注意,BigDecimal.scale
实际上不是指数。对于BigDecimal
,