Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Wrapping around very large angles to [0,2*PI] adds too big numerical error

In below sample, I try different methods to wrap an angle between 0 and 2 x PI. While doing this to compute cosine of same angles, both methods cause a different amount of numerical error compared to the standard std::cos(original angle that is non-wrapped around):

#include <iostream>
#include <cmath>

float fmodfast(float angle)
{
    constexpr float twoPi = 2.0 * 3.141592865358979;
    constexpr float twoPiInv = 1.0/twoPi;
    auto r =  angle - twoPi * floor( angle *twoPiInv) ;
    if(r<0)
    return r+2.0 * 3.141592865358979;
    else
    return r;
}

float fmodn(float f)
{
    auto r = std::fmod(f,2.0 * 3.141592865358979);
    if(r<0)
    return r + 2.0 * 3.141592865358979;
    else
    return r;
}

int main()
{
    for(int i=-100;i<=100;i++)
    {
        float f = 100000000.0f*i;
        std::cout<<f<<" "<<std::cos(f)<<" "<<std::cos(fmodn(f))<<" "<<std::cos(fmodfast(f))<<std::endl;
    }
    return 0;
}

output:

-1e+10 0.87312 -0.659246 0.566338
-9.9e+09 -0.605079 0.624035 0.907523
-9.8e+09 0.386995 -0.451729 0.966069
-9.7e+09 0.0143294 0.4103 0.699183
-9.6e+09 -0.413259 -0.368006 0.236586
-9.5e+09 0.743126 0.324936 -0.292121
-9.4e+09 -0.948805 -0.281181 -0.739178
-9.3e+09 0.997629 0.0797464 -0.999019
-9.2e+09 -0.941808 -0.033905 -0.881843
-9.1e+09 0.728594 -0.0120074 -0.517957
-9e+09 -0.534379 0.215498 0.149652
-8.9e+09 0.151487 -0.260095 0.633131
-8.8e+09 0.256721 0.304145 0.939413
-8.7e+09 -0.622026 -0.347552 0.982845
-8.6e+09 0.883381 0.390228 0.751266
-8.5e+09 -0.972451 -0.569644 0.15466
-8.4e+09 0.984477 0.606771 -0.370933
-8.3e+09 -0.831981 -0.642619 -0.792816
-8.2e+09 -0.605642 -0.733507 0.999185
-8.1e+09 -0.313118 -0.812848 -0.839406
-8e+09 -0.0930906 0.838729 -0.444749
-7.9e+09 0.483742 -0.862841 0.0744413
-7.8e+09 0.742653 -0.919348 -0.636155
-7.7e+09 0.920407 -0.961381 0.964748
-7.6e+09 -0.99995 0.973001 0.964021
-7.5e+09 0.912384 -0.98257 0.693554
-7.4e+09 0.729078 -0.998114 -0.150839
-7.3e+09 0.466099 -0.997944 -0.44715
-7.2e+09 -0.0731113 0.99395 -0.840921
-7.1e+09 -0.332095 -0.987861 -0.999333
-7e+09 -0.621473 -0.960632 0.837297
-6.9e+09 -0.842937 -0.918279 -0.368436
-6.8e+09 0.987798 0.899137 0.15742
-6.7e+09 -0.967582 -0.878099 0.639134
-6.6e+09 -0.832373 -0.811268 -0.965777
-6.5e+09 -0.606204 -0.731665 0.938477
-6.4e+09 0.237293 0.699603 0.63099
-6.3e+09 0.171273 -0.666066 0.146945
-6.2e+09 0.483124 -0.567417 0.450656
-6.1e+09 0.742179 -0.459834 -0.88313
-6e+09 -0.948357 0.418588 -0.998893
-5.9e+09 0.996049 -0.376458 -0.835147
-5.8e+09 0.912673 -0.25748 0.364789
-5.7e+09 0.729562 -0.134448 0.239247
-5.6e+09 -0.39492 0.0888206 0.7011
-5.5e+09 -0.00571906 -0.0430046 0.966773
-5.4e+09 -0.331428 0.0824449 -0.937129
-5.3e+09 -0.620919 0.206597 0.564032
-5.2e+09 0.882717 -0.251292 0.0638678
-5.1e+09 -0.997 0.295457 -0.454168
-5e+09 -0.96776 0.412768 0.884964
-4.9e+09 -0.832765 0.52358 -0.991482
-4.8e+09 0.541637 -0.562136 -0.786322
-4.7e+09 -0.159993 0.599508 -0.361133
-4.6e+09 0.170576 0.695016 -0.243052
-4.5e+09 0.482505 0.779582 0.758174
-4.4e+09 -0.792692 -0.80751 0.984737
-4.3e+09 0.970407 0.833735 0.935753
-4.2e+09 0.996112 0.896318 -0.560834
-4.1e+09 -0.444049 -0.365029 0.999796
-4e+09 -0.67339 -0.958835 -0.526902
-3.9e+09 0.933449 0.200814 -0.426532
-3.8e+09 -0.00501223 0.993227 0.990961
-3.7e+09 -0.929806 -0.0307075 -0.651597
-3.6e+09 0.680767 -0.998486 -0.282036
-3.5e+09 0.435044 -0.140299 0.958462
-3.4e+09 -0.996945 0.974458 -0.760724
-3.3e+09 0.289505 0.307191 -0.130821
-3.2e+09 0.786541 -0.921847 0.903051
-3.1e+09 -0.86114 -0.465072 -0.851661
-3e+09 -0.16069 0.842196 0.0235201
-2.9e+09 0.977925 0.609311 0.82607
-2.8e+09 -0.550036 -0.737842 -0.922253
-2.7e+09 -0.578175 -0.735678 0.177301
-2.6e+09 0.970236 0.611845 0.729344
-2.5e+09 -0.126964 0.840466 -0.970815
-2.4e+09 -0.877963 -0.467902 0.326861
-2.3e+09 0.765041 -0.920602 0.6152
-2.2e+09 0.321954 0.310234 -0.996177
-2.1e+09 -0.999027 0.973734 0.468597
-2e+09 0.40411 -0.143466 0.486363
-1.9e+09 0.705332 -0.998305 -0.997738
-1.8e+09 -0.916724 -0.0275091 0.59915
-1.7e+09 -0.0390845 0.993594 0.345888
-1.6e+09 0.94513 0.197678 -0.975461
-1.5e+09 -0.647808 -0.959738 0.715374
-1.4e+09 -0.474323 -0.362048 0.197164
-1.3e+09 0.992531 0.897732 -0.929878
-1.2e+09 -0.24702 0.5158 0.814514
-1.1e+09 -0.813005 -0.809393 0.0437215
-1e+09 0.837887 -0.654421 -0.86208
-9e+08 0.204053 0.697313 0.894191
-8e+08 -0.986187 0.773847 -0.110766
-7e+08 0.512678 -0.564779 -0.773681
-6e+08 0.613588 -0.870574 0.9525
-5e+08 -0.958615 0.41568 -0.262603
-4e+08 0.0831051 0.941766 -0.666796
-3e+08 0.898217 -0.254387 0.988054
-2e+08 -0.735903 -0.985334 -0.408169
-1e+08 -0.363385 0.0856332 -0.543981
0 1 1 1
1e+08 -0.363385 0.0856329 -0.543981
2e+08 -0.735903 -0.985334 -0.408169
3e+08 0.898217 -0.254387 0.988054
4e+08 0.0831051 0.941766 -0.666796
5e+08 -0.958615 0.41568 -0.262603
6e+08 0.613588 -0.870575 0.9525
7e+08 0.512678 -0.564779 -0.773681
8e+08 -0.986187 0.773847 -0.110767
9e+08 0.204053 0.697313 0.89419
1e+09 0.837887 -0.654421 -0.86208
1.1e+09 -0.813005 -0.809393 0.0437209
1.2e+09 -0.24702 0.5158 0.814513
1.3e+09 0.992531 0.897732 -0.929877
1.4e+09 -0.474323 -0.362049 0.197164
1.5e+09 -0.647808 -0.959738 0.715375
1.6e+09 0.94513 0.197679 -0.975461
1.7e+09 -0.0390845 0.993594 0.345886
1.8e+09 -0.916724 -0.0275096 0.599152
1.9e+09 0.705332 -0.998305 -0.997738
2e+09 0.40411 -0.143466 0.486363
2.1e+09 -0.999027 0.973735 0.468597
2.2e+09 0.321954 0.310234 -0.996177
2.3e+09 0.765041 -0.920602 0.615201
2.4e+09 -0.877963 -0.467901 0.326864
2.5e+09 -0.126964 0.840467 -0.970815
2.6e+09 0.970236 0.611845 0.729342
2.7e+09 -0.578175 -0.735678 0.177302
2.8e+09 -0.550036 -0.737841 -0.922253
2.9e+09 0.977925 0.609311 0.826071
3e+09 -0.16069 0.842196 0.0235226
3.1e+09 -0.86114 -0.465072 -0.851663
3.2e+09 0.786541 -0.921847 0.90305
3.3e+09 0.289505 0.307191 -0.130818
3.4e+09 -0.996945 0.974458 -0.760726
3.5e+09 0.435044 -0.1403 0.958461
3.6e+09 0.680767 -0.998486 -0.282033
3.7e+09 -0.929806 -0.0307068 -0.651599
3.8e+09 -0.00501223 0.993227 0.990963
3.9e+09 0.933449 0.200813 -0.42653
4e+09 -0.67339 -0.958835 -0.526902
4.1e+09 -0.444049 -0.365029 0.999796
4.2e+09 0.996112 0.896318 -0.560833
4.3e+09 0.970407 0.833735 0.935752
4.4e+09 -0.792692 -0.80751 0.984737
4.5e+09 0.482505 0.779583 0.758174
4.6e+09 0.170576 0.695016 -0.243055
4.7e+09 -0.159993 0.599508 -0.361131
4.8e+09 0.541637 -0.562136 -0.78632
4.9e+09 -0.832765 0.52358 -0.991482
5e+09 -0.96776 0.412768 0.884965
5.1e+09 -0.997 0.295458 -0.454157
5.2e+09 0.882717 -0.251292 0.0638805
5.3e+09 -0.620919 0.206597 0.564043
5.4e+09 -0.331428 0.0824454 -0.937128
5.5e+09 -0.00571906 -0.0430041 0.966773
5.6e+09 -0.39492 0.0888199 0.701101
5.7e+09 0.729562 -0.134448 0.239247
5.8e+09 0.912673 -0.257479 0.364786
5.9e+09 0.996049 -0.376457 -0.835145
6e+09 -0.948357 0.418587 -0.998893
6.1e+09 0.742179 -0.459834 -0.883132
6.2e+09 0.483124 -0.567416 0.450658
6.3e+09 0.171273 -0.666065 0.146957
6.4e+09 0.237293 0.699602 0.631
6.5e+09 -0.606204 -0.731664 0.938476
6.6e+09 -0.832373 -0.811267 -0.965773
6.7e+09 -0.967582 -0.878098 0.639135
6.8e+09 0.987798 0.899137 0.157407
6.9e+09 -0.842937 -0.918279 -0.368437
7e+09 -0.621473 -0.960632 0.837297
7.1e+09 -0.332095 -0.987861 -0.999333
7.2e+09 -0.0731113 0.99395 -0.840914
7.3e+09 0.466099 -0.997944 -0.447153
7.4e+09 0.729078 -0.998114 -0.150837
7.5e+09 0.912384 -0.98257 0.693552
7.6e+09 -0.99995 0.973001 0.964016
7.7e+09 0.920407 -0.961381 0.964748
7.8e+09 0.742653 -0.919348 -0.636145
7.9e+09 0.483742 -0.862841 0.0744286
8e+09 -0.0930906 0.838729 -0.444747
8.1e+09 -0.313118 -0.812848 -0.839413
8.2e+09 -0.605642 -0.733508 0.999184
8.3e+09 -0.831981 -0.642619 -0.792808
8.4e+09 0.984477 0.606772 -0.370932
8.5e+09 -0.972451 -0.569644 0.154672
8.6e+09 0.883381 0.390229 0.751264
8.7e+09 -0.622026 -0.347553 0.982842
8.8e+09 0.256721 0.304145 0.939414
8.9e+09 0.151487 -0.260096 0.633145
9e+09 -0.534379 0.215498 0.149654
9.1e+09 0.728594 -0.0120078 -0.517955
9.2e+09 -0.941808 -0.0339047 -0.881849
9.3e+09 0.997629 0.079746 -0.99902
9.4e+09 -0.948805 -0.281181 -0.739169
9.5e+09 0.743126 0.324936 -0.292122
9.6e+09 -0.413259 -0.368005 0.236598
9.7e+09 0.0143294 0.4103 0.699183
9.8e+09 0.386995 -0.451728 0.966072
9.9e+09 -0.605079 0.624035 0.907524
1e+10 0.87312 -0.659246 0.566327

The error diminishes when input angle approaches zero. What is the cause of this floating-point error and how does std::cos solve this problem inside the implementation?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

If f is not multiplied by 100000000.0f but 1000.0f then both versions compute very close to std::cos(original angle) with the error on the order of only 0.0001.

Is there a way to wrap around the angle to the range of [0,2pi] without losing any accuracy/precision (without skewing the real angle wrap-around between 0-2pi)? Or, does std::cos not use float inside? I assume it is using float in all parts of algorithm but I may be wrong.

>Solution :

There is a typo in the pi constants:

3.141592865358979
        ^

The correct value is

3.1415926535897932384626433832795

cppreference like https://en.cppreference.com/w/cpp/numeric/math/cos uses

const double pi = std::acos(-1);

to get pi.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading