English 中文(简体)
• 起草一部关于发现机器丝网的代码
原标题:Trying to write a code for finding the machine epsilon

我正试图确定C中各种浮动点格式的精确度(即浮动、双重和长期双重)。 目前使用的是Im。

#include <stdio.h>
#define N 100000

int main(void)
{
   float max = 1.0, min = 0.0, test;
   int i;                              /* Counter for the conditional loop */

   for (i = 0; i < N; i++) {
      test = (max + min) / 2.0;
      if( (1.0 + test) != 1.0)         /* If too high, set max to test and try again */
     max = test;
  if( (1.0 + test) == 1.0)     /* If too low, set min to test and try again */
         min = test;
   }
   printf("The epsilon machine is %.50lf
", max);
   return 0;
}

这使预期值约为2 ^-64。 然而,当我把欺骗变成两倍或长倍时,我获得同样的答案时,我应当获得较小的价值,但我却不这样做。 没有人会提出想法?

最佳回答

猜测你为何重新获得同样的答案:

if( (1.0 + test) != 1.0)

这1.0是两倍不变的,因此,它使你的浮体翻了一番,使添加成为两倍。 您可能希望在此宣布一个临时浮标,以补充或使这些浮数不变(1.0f IIRC)。

您还可能陷入过度偏袒的临时性血压问题,可能需要迫使其储存中间商,以降低准确度。


这里可以迅速用你的范围搜索方法,但用正确的类型计算测试。 不过,我得到的答案略为大。

#include <stdio.h>
#define N 100000
#define TYPE float

int main(void)
{
   TYPE max = 1.0, min = 0.0, test;
   int i;

   for (i = 0; i < N; i++)
   {
      TYPE one_plus_test;

      test = (max + min) / ((TYPE)2.0);
      one_plus_test = ((TYPE)1.0) + test;
      if (one_plus_test == ((TYPE)1.0))
      {
         min = test;
      }
      else
      {
         max = test;
      }
   }
   printf("The epsilon machine is %.50lf
", max);
   return 0;
}
问题回答

它取决于你通过“怀孕水平”的含义。

浮动点数具有“正常”(热)数值,但也有特殊和次要数字。 如果你想确定不同的限额,则C标准预先界定了不变值:

#include <math.h>
#include <stdio.h>
#include <float.h>

int main(void)
{
    printf("%30s: %g
", "FLT_EPSILON", FLT_EPSILON);
    printf("%30s: %g
", "FLT_MIN", FLT_MIN);
    printf("%30s: %g
", "nextafterf(0.0, 1.0)", nextafterf(0.0, 1.0));
    printf("%30s: %g
", "nextafterf(1.0, 2.0)-1", (nextafterf(1.0, 2.0) - 1.0f));
    puts("");
    printf("%30s: %g
", "DBL_EPSILON", DBL_EPSILON);
    printf("%30s: %g
", "DBL_MIN", DBL_MIN);
    printf("%30s: %g
", "nextafter(0.0, 1.0)", nextafter(0.0, 1.0));
    printf("%30s: %g
", "nextafter(1.0, 2.0)-1", (nextafter(1.0, 2.0) - 1.0));
    puts("");
    printf("%30s: %Lg
", "LDBL_EPSILON", LDBL_EPSILON);
    printf("%30s: %Lg
", "LDBL_MIN", LDBL_MIN);
    printf("%30s: %Lg
", "nextafterl(0.0, 1.0)", nextafterl(0.0, 1.0));
    printf("%30s: %Lg
", "nextafterl(1.0, 2.0)-1", (nextafterl(1.0, 2.0) - 1.0));
    return 0;
}

以上方案每类印刷4个数值:

  • the difference between 1 and the least value greater than 1 in that type (TYPE_EPSILON),
  • the minimum positive normalized value in a given type (TYPE_MIN). This does not include subnormal numbers,
  • the minimum positive value in a given type (nextafter*(0...)). This includes subnormal numbers,
  • the minimum number greater than 1. This is the same as TYPE_EPSILON, but calculated in a different way.

根据你“割礼”的含义,上述任何东西都对你有用。

以上方案在我的电脑上的产出如下:

               FLT_EPSILON: 1.19209e-07
                   FLT_MIN: 1.17549e-38
      nextafterf(0.0, 1.0): 1.4013e-45
    nextafterf(1.0, 2.0)-1: 1.19209e-07

               DBL_EPSILON: 2.22045e-16
                   DBL_MIN: 2.22507e-308
       nextafter(0.0, 1.0): 4.94066e-324
     nextafter(1.0, 2.0)-1: 2.22045e-16

              LDBL_EPSILON: 1.0842e-19
                  LDBL_MIN: 3.3621e-4932
      nextafterl(0.0, 1.0): 3.6452e-4951
    nextafterl(1.0, 2.0)-1: 1.0842e-19

我不相信你的算法应该如何发挥作用。 (C++) 提供了正确的答案:

#include <iostream>

template<typename T>
int epsilon() {
    int pow = 0;
    T eps = 1;
    while (eps + 1 != 1) {
        eps /= 2;
        --pow;
    }
    return pow + 1;
}

int main() {
    std::cout << "Epsilon for float: 2^" << epsilon<float>() <<  
 ;
    std::cout << "Epsilon for double: 2^" << epsilon<double>() <<  
 ;
}

这相当于最小值,因此,如果加上1,仍可区分1。

产出:

Epsilon for float: 2^-23
Epsilon for double: 2^-52

744个浮动点格式的财产,在重新解释同一宽度的两种补充时,它们单单地增加积极价值,单单单单地减少负值(见32个轨道浮动的双位代表)。 他们还拥有以下财产:0 < «f(x)<∞, and >f(x+1) - f(x) ≥ |f (x) |f(x) ——f(x) ; f(x) 是重新解释x)。 以允许打字和始终使用ISO 754-1985的语文,我们可以利用这种语言,不断计算机器ep。 例如,在C:

typedef union {
  long long i64;
  double d64;
} dbl_64;

double machine_eps (double value)
{
    dbl_64 s;
    s.d64 = value;
    s.i64++;
    return s.d64 - value;
}

https://en.wikipedia.org/wiki/Machine_epsilon”rel=“nofollow”https://en.wikipedia.org/wiki/Machine_epsilon

我要补充的是,通过使用<条码>长期双,你可以从浮动点计算中获得最高精确度。

为适用于@Rups解决方案,仅改动TYPElong Double>:

printf("The epsilon machine is %.50Lf
", max);

这是我机器上的Epsilon,使用float:

0.00000005960465188081798260100185871124267578125000

并且使用<条码>长期双:

0.00000000000000000005421010862427522170625011179761

差异很大。

这种代码的一个问题是,汇编者将把浮动点变量输入微处理器的浮动点登记册。 如果你的微处理器只拥有两倍精确的浮动点登记册,那么对<代码>float double的精确度也将相同。

你们需要找到一种办法,迫使汇编者将浮动点值重新储存到每两种计算(即正确类型变量)之间的记忆中。 这样,它就不得不放弃登记册的进一步精确性。 但今天,汇编者正在优化你的法典。 因此,这很难实现。





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签