3

我有这个代码:

return 1.0 / (1 + exp(-x));

它用于计算给定 x 的 sigmoid 函数的值。问题是它总是返回 1.00000

我开始浏览代码以查看它失败的地方,然后我得到了这个:

long double expV = exp(-x);
long double btm = (1 + expV);
long double calc = 1.0 / btw;

现在变量的值是:

(long double) expV = 3.0356148105583944943E-165
(long double) btm = 1
(long double) calc = 1

所以我的问题是如何解决问题,我应该使用另一种类型的变量还是应该更改代码中的某些内容?

Update btm should be of value: 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030356148105583944943 as WolframAplha said

x 的值为 1,x 的类型是 double 而不是 long double。我将其更改为 long double 并报告。

4

2 回答 2

3

编辑:抱歉,NSDecimalNumber 中的指数支持从 -128 到 127,所以在这种特殊情况下不起作用,但它对定点算术计算很有用

以前的答案: NSDecimalNumber

NSDecimalNumber* expV = [NSDecimalNumber decimalNumberWithMantissa:3.0356148105583944943
                                          exponent:-165
                                          isNegative:NO];
NSDecimalNumber* k = [NSDecimalNumber decimalNumberWithString:@"2.0"];

NSDecimalNumber* btm = [expV decimalNumberByAdding:k];

NSDecimalNumber* calc = [k decimalNumberByDividingBy:btm];

可能不是最优雅的方式:/

于 2013-09-27T07:11:19.130 回答
3

这里的问题是 long double 的精度不足以应对如此小的加法(在 的情况下btm)。'1' 超过了微小的expV,因此,在 long double 的精度范围内,btm它只是 1。

在回答您的问题时,您的代码很好:逻辑上没有错,您只需要更精确的数据类型。不幸的是,Objective-C 没有提供一个(这里有一些关于 Objective-C 中任意精度的讨论)。但是,如果您愿意走得更远一点,GNU MP 库(和其他库)将能够帮助您解决任意精度的数学问题。当然,任意精确的数学是以性能为代价的——可悲的是,没有免费的午餐。

于 2013-09-27T07:16:35.230 回答