fork(1) download
  1. #include <iomanip>
  2. #include <iostream>
  3. #include <math.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6.  
  7. using namespace std;
  8.  
  9. enum subtractionMethod { REGULAR_SUBTRACTION, SHIFTED_SUBTRACTION, ARITHMETIC_CONJUGATE };
  10. double subtract(double& x, double& y, subtractionMethod theMethod)
  11. {
  12. //check for theMethod
  13. switch (theMethod)
  14. {
  15. case REGULAR_SUBTRACTION:
  16. return (x-y);
  17. case SHIFTED_SUBTRACTION:
  18. {
  19. //we will lose -log2(1-y/x) bits of precision
  20. int bitsLost = (int)ceil(-1*log2(1-y/x));
  21. int scaleFactor = (int)(pow(2,bitsLost));
  22. //attempting to multiply both arguments by 2^bitCount, subtract, and divide back
  23. return (x*scaleFactor-y*scaleFactor)/scaleFactor;
  24. }
  25. case ARITHMETIC_CONJUGATE:
  26. return (x*x-y*y)/(x+y);
  27. default:
  28. return 0; //code should NEVER reach here!!
  29. }
  30. }
  31.  
  32. int main()
  33. {
  34. double x = 0, y = 1000000;
  35. //seed the random number generator
  36. srand(time(0));
  37. //generate 2 random numbers between 1 and 1000000
  38. x = (double)(rand() % 1000000 + 1);
  39. while (y > x)
  40. y = (double)(rand() % 1000000 + 1);
  41. //divide both numbers by 1E15
  42. x /= 1E15;
  43. y /= 1E15;
  44. //report x and y
  45. cout << setprecision(15) << showpoint << fixed;
  46. cout << "x == " << x << "\ny == " << y << endl;
  47. //attempt to subtract them and print them to screen
  48. //first via straight subtraction
  49. cout << "x-y by straight subtraction is: " << subtract(x,y,REGULAR_SUBTRACTION) << endl;
  50. //next, by bit-shifting
  51. cout << "x-y by shifting is :" << subtract(x,y,SHIFTED_SUBTRACTION) << endl;
  52. //finally by arithmetic conjugate
  53. cout << "x-y by arithmetic conjugate is: " << subtract(x,y,ARITHMETIC_CONJUGATE) << endl;
  54.  
  55. return 0;
  56. }
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
x == 0.000000000547883
y == 0.000000000326355
x-y by straight subtraction is: 0.000000000221528
x-y by shifting is :0.000000000221528
x-y by arithmetic conjugate is: 0.000000000221528