Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Objective-C中获取NSDecimalNumber的指数?_Objective C_Ios - Fatal编程技术网

在Objective-C中获取NSDecimalNumber的指数?

在Objective-C中获取NSDecimalNumber的指数?,objective-c,ios,Objective C,Ios,给定一个小数点,我怎样才能找到指数(标度) 虽然原则上可以先转换成NSString,然后再进行一些丑陋的字符串操作,但我宁愿避免这样做 使用Java BigDecimal,我可以调用该方法来获取比例 对于NSDecimalNumber是否存在类似的简洁方法?不,它看起来没有等效方法。我想你可能得自己写 但是,如果您不介意仔细研究一下(并忽略文档警告),您可以查看从中返回的-它有许多字段,您可以访问这些字段。主观上,这比NSString操作更好还是更差取决于您。如果出于某种原因确实需要指数(而不是

给定一个小数点,我怎样才能找到指数(标度)

虽然原则上可以先转换成NSString,然后再进行一些丑陋的字符串操作,但我宁愿避免这样做

使用Java BigDecimal,我可以调用该方法来获取比例

对于NSDecimalNumber是否存在类似的简洁方法?

不,它看起来没有等效方法。我想你可能得自己写


但是,如果您不介意仔细研究一下(并忽略文档警告),您可以查看从中返回的-它有许多字段,您可以访问这些字段。主观上,这比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