c++ - 3D Vector normalization issue -


I found a problem with the 3D vector normalization, Vector changes

Example code:

 < Code> Vector3 v1 (-0.9650 9453265, -0.210381150246, 0.156014174223); Std :: cout.precision (15); V1.normalize (); Std :: cout & lt; & Lt; V1 & lt; & Lt; Std :: endl; V1.normalize (); Std :: cout & lt; & Lt; V1 & lt; & Lt; Std :: endl; V1.normalize (); Std :: cout & lt; & Lt; V1 & lt; & Lt; Std :: endl; V1.normalize (); Std :: cout & lt; & Lt; V1 & lt; & Lt; Std :: endl;   

Output: -0.965090330430436 -0.265090453624725 -0.210381150245667 0.156014174222946 -0.965090334415436 -0.210381120443344 0.156014159321785 -0.965090453624725 -0.210381150245667.1156014174222946

General function:

  zero Vector3 :: normal () {if (length () == 0) return; Vector 3x = * this; Float sqr = x.x * x.x + x.y * x.y + x.z * x.z; * This = x * (1.0 F / STD :: SQLT (SKR)); }   

Is this a problem with float exact, or is there anything wrong with my code? How to avoid this problem?

Edit: Just find out why I can not recreate the problem.

If I change x * = ((t) 1.) / len x / = len So I actually gave you the floats , that is, the first six digits (which you should not trust at anyway float ) end with answers incompatible :

  -0965090334415436 -0210381120443344,156014159321785 -0965090453624725 -0,210381150245667,156014174222946 -0965090334415436 -0210381120443344,156014159321785 -0965090453624725 -0 As expected,  duplicates  A, 210381150245667, 0156014174222946 -0965090334415436 -0210381120443344,156014159321785   

Minister are also right up to the 15th digit:

  -0,965090340387771 -0,210381125639766 0,156014155975542 -0,965090340387771 -0,210381125639766 0,156014155975542 -0,965090340387771 -0,210381125639766 0,156 014155975542 -0,965090340387771 -0,210381125639766 0,156014155975542 -0,965090340387771 -0,210381125639766 0,156014155975542   

However, name The result is always consistent with the first six digits.

Original post:

It looks like "just a floating point exact issue", since single-precise floats are only given to you above I checked it Code is written for me and my results are not as bad as you do # include & lt; Semith & gt; Template & lt; Typename t & gt; Square vector 3 {public: t x; TY; TZ; Vector3 (tx, ty, tz): x (x), y (y), z (z) {} minus normal () {t len ​​= std :: sqrt (x * x + y * y + z * Z); If (lane! = 0.) {x / = len; Y / = Lennon; Z / = len; }} Void println () {std :: cout & lt; & Lt; X & LT; & Lt; "" & Lt; & Lt; Y & lt; & Lt; "" & Lt; & Lt; J & lt; & Lt; Std :: endl; }}; Int main (int argc, char ** argv) {std :: cout.precision (15); Vector3 & LT; Float & gt; V (-0.9650 9 0833265, -0.210381150246, 0.156014174223); For (int i = 0; i <5; ++ i) {v.normalize (); V.println (); } Return 0; }

Output:

  -0,965090334415436 -0,210381120443344 0,156014159321785 -0,965090394020081 -0,210381135344505 0,156014174222946 -0,965090394020081 -0,210381135344505 0,156014174222946 -0,965090394020081 -0,210381135344505 0,156014174222946 -0,965090394020081 -0,210381135344505 0,156014174222946   

change Vector3 & LT; Float & gt; Vector3 & lt; Double & gt; gives consistent results up to 15 points:

  -0,965090340387771 -0,210381125639766 0,156014155975542 -0,965090340387771 -0,210381125639766 0,156014155975542 -0,965090340387771 - 0,210381125639766 0,156014155975542 -0,965090340387771 -0,210381125639766 0,156014155975542 -0,965090340387771 -0,210381125639766 0,156014155975542   

Notice that even where Boat changed the outcome, the number above the first seven digits is not really true.

Comments

Popular posts from this blog

c - Mpirun hangs when mpi send and recieve is put in a loop -

python - Apply coupon to a customer's subscription based on non-stripe related actions on the site -

java - Unable to get JDBC connection in Spring application to MySQL -