Advertisement
Geometrian

Testing Error for `pow(x,1/2.4)` for sRGB Conversion

Oct 26th, 2022
878
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 1.18 KB | Science | 0 0
  1. //https://math.stackexchange.com/a/3494710
  2. //Compile with C++20
  3.  
  4. #include <bit>
  5. #include <cmath>
  6. #include <cstdint>
  7. #include <cstdio>
  8.  
  9. float test(float x) {
  10.     auto negtwelfth_root = [](float a) {
  11.         float r = std::bit_cast<float>( 0x44c3cf20 - (std::bit_cast<uint32_t>(a)>>16)*0x1555 );
  12.         float r3=r*r*r; float r6=r3*r3; float r12=r6*r6;
  13.         float h = 0x1.ff078cp-1f - r12*a;
  14.         r = (0x1.61bf5ap-4f + 0x1.905614p-5f*h)*h*r + r;
  15.         return r;
  16.     };
  17.     return std::sqrt(x) * negtwelfth_root(x);
  18. }
  19. double gt(float x) {
  20.     return std::pow( (double)x, 1.0/2.4 );
  21. }
  22.  
  23. int main() {
  24.     uint32_t start = std::bit_cast<uint32_t>( std::nextafter(0.0031308f,9999.0f) );
  25.     uint32_t stop  = std::bit_cast<uint32_t>( 1.0f );
  26.  
  27.     double maxerr    = 0.0;
  28.     double maxrelerr = 0.0;
  29.     for (uint32_t a=start;a<=stop;++a) {
  30.         float x = std::bit_cast<float>(a);
  31.  
  32.         float  res = test(x);
  33.         double ref = gt(x);
  34.         double err    = std::abs( res-ref );
  35.         double relerr = std::abs( (res-ref) / ref );
  36.         if (err   >maxerr   ) maxerr   =err   ;
  37.         if (relerr>maxrelerr) maxrelerr=relerr;
  38.     }
  39.     printf("maxerr    = %11.4e\n",maxerr   );
  40.     printf("maxrelerr = %11.4e\n",maxrelerr);
  41.     getchar();
  42.  
  43.     return EXIT_SUCCESS;
  44. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement