#include <iomanip>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
enum subtractionMethod { REGULAR_SUBTRACTION, SHIFTED_SUBTRACTION, ARITHMETIC_CONJUGATE } ;
double subtract( double & x, double & y, subtractionMethod theMethod)
{
//check for theMethod
switch ( theMethod)
{
case REGULAR_SUBTRACTION:
return ( x- y) ;
case SHIFTED_SUBTRACTION:
{
//we will lose -log2(1-y/x) bits of precision
int bitsLost = ( int ) ceil ( - 1 * log2( 1 - y/ x) ) ;
int scaleFactor = ( int ) ( pow ( 2 ,bitsLost) ) ;
//attempting to multiply both arguments by 2^bitCount, subtract, and divide back
return ( x* scaleFactor- y* scaleFactor) / scaleFactor;
}
case ARITHMETIC_CONJUGATE:
return ( x* x- y* y) / ( x+ y) ;
default :
return 0 ; //code should NEVER reach here!!
}
}
int main( )
{
double x = 0 , y = 1000000 ;
//seed the random number generator
srand ( time ( 0 ) ) ;
//generate 2 random numbers between 1 and 1000000
x = ( double ) ( rand ( ) % 1000000 + 1 ) ;
while ( y > x)
y = ( double ) ( rand ( ) % 1000000 + 1 ) ;
//divide both numbers by 1E15
x / = 1E15 ;
y / = 1E15 ;
//report x and y
cout << setprecision( 15 ) << showpoint << fixed;
cout << "x == " << x << "\n y == " << y << endl;
//attempt to subtract them and print them to screen
//first via straight subtraction
cout << "x-y by straight subtraction is: " << subtract( x,y,REGULAR_SUBTRACTION) << endl;
//next, by bit-shifting
cout << "x-y by shifting is :" << subtract( x,y,SHIFTED_SUBTRACTION) << endl;
//finally by arithmetic conjugate
cout << "x-y by arithmetic conjugate is: " << subtract( x,y,ARITHMETIC_CONJUGATE) << endl;
return 0 ;
}
I2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPG1hdGguaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dGltZS5oPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmVudW0gc3VidHJhY3Rpb25NZXRob2QgeyBSRUdVTEFSX1NVQlRSQUNUSU9OLCBTSElGVEVEX1NVQlRSQUNUSU9OLCBBUklUSE1FVElDX0NPTkpVR0FURSB9Owpkb3VibGUgc3VidHJhY3QoZG91YmxlJiB4LCBkb3VibGUmIHksIHN1YnRyYWN0aW9uTWV0aG9kIHRoZU1ldGhvZCkKewoJLy9jaGVjayBmb3IgdGhlTWV0aG9kCglzd2l0Y2ggKHRoZU1ldGhvZCkKCXsKCQljYXNlIFJFR1VMQVJfU1VCVFJBQ1RJT046CgkJCXJldHVybiAoeC15KTsKCQljYXNlIFNISUZURURfU1VCVFJBQ1RJT046CgkJewoJCQkvL3dlIHdpbGwgbG9zZSAtbG9nMigxLXkveCkgYml0cyBvZiBwcmVjaXNpb24KCQkJaW50IGJpdHNMb3N0ID0gKGludCljZWlsKC0xKmxvZzIoMS15L3gpKTsKCQkJaW50IHNjYWxlRmFjdG9yID0gKGludCkocG93KDIsYml0c0xvc3QpKTsKCQkJLy9hdHRlbXB0aW5nIHRvIG11bHRpcGx5IGJvdGggYXJndW1lbnRzIGJ5IDJeYml0Q291bnQsIHN1YnRyYWN0LCBhbmQgZGl2aWRlIGJhY2sKCQkJcmV0dXJuICh4KnNjYWxlRmFjdG9yLXkqc2NhbGVGYWN0b3IpL3NjYWxlRmFjdG9yOwoJCX0KCQljYXNlIEFSSVRITUVUSUNfQ09OSlVHQVRFOgoJCQlyZXR1cm4gKHgqeC15KnkpLyh4K3kpOwoJCWRlZmF1bHQ6CgkJCXJldHVybiAwOwkvL2NvZGUgc2hvdWxkIE5FVkVSIHJlYWNoIGhlcmUhIQoJfQp9CgppbnQgbWFpbigpIAp7Cglkb3VibGUgeCA9IDAsIHkgPSAxMDAwMDAwOwoJLy9zZWVkIHRoZSByYW5kb20gbnVtYmVyIGdlbmVyYXRvcgoJc3JhbmQodGltZSgwKSk7CgkvL2dlbmVyYXRlIDIgcmFuZG9tIG51bWJlcnMgYmV0d2VlbiAxIGFuZCAxMDAwMDAwCgl4ID0gKGRvdWJsZSkocmFuZCgpICUgMTAwMDAwMCArIDEpOwoJd2hpbGUgKHkgPiB4KQoJCXkgPSAoZG91YmxlKShyYW5kKCkgJSAxMDAwMDAwICsgMSk7CgkvL2RpdmlkZSBib3RoIG51bWJlcnMgYnkgMUUxNQoJeCAvPSAxRTE1OwoJeSAvPSAxRTE1OwoJLy9yZXBvcnQgeCBhbmQgeQoJY291dCA8PCBzZXRwcmVjaXNpb24oMTUpIDw8IHNob3dwb2ludCA8PCBmaXhlZDsKCWNvdXQgPDwgInggPT0gIiA8PCB4IDw8ICJcbnkgPT0gIiA8PCB5IDw8IGVuZGw7CgkvL2F0dGVtcHQgdG8gc3VidHJhY3QgdGhlbSBhbmQgcHJpbnQgdGhlbSB0byBzY3JlZW4KCS8vZmlyc3QgdmlhIHN0cmFpZ2h0IHN1YnRyYWN0aW9uCgljb3V0IDw8ICJ4LXkgYnkgc3RyYWlnaHQgc3VidHJhY3Rpb24gaXM6ICIgPDwgc3VidHJhY3QoeCx5LFJFR1VMQVJfU1VCVFJBQ1RJT04pIDw8IGVuZGw7CgkvL25leHQsIGJ5IGJpdC1zaGlmdGluZwoJY291dCA8PCAieC15IGJ5IHNoaWZ0aW5nIGlzIDoiIDw8IHN1YnRyYWN0KHgseSxTSElGVEVEX1NVQlRSQUNUSU9OKSA8PCBlbmRsOwoJLy9maW5hbGx5IGJ5IGFyaXRobWV0aWMgY29uanVnYXRlCgljb3V0IDw8ICJ4LXkgYnkgYXJpdGhtZXRpYyBjb25qdWdhdGUgaXM6ICIgPDwgc3VidHJhY3QoeCx5LEFSSVRITUVUSUNfQ09OSlVHQVRFKSA8PCBlbmRsOwoJCglyZXR1cm4gMDsKfQ==