#include #include // compiled with "g++ -std=c++11 -fsanitize=undefined -g fractional_test.cpp" using gcc 5.4 for x86_64 on linux // start copied from CglGomory.cpp typedef struct { int numerator; int denominator; } Rational; inline Rational nearestRational(double value, int maxDenominator) { Rational tryThis; Rational tryA; Rational tryB; double integerPart; #if CGL_DEBUG>1 printf("Rational of %g is ",value); #endif int nLoop=0; tryA.numerator=0; tryA.denominator=1; tryB.numerator=1; tryB.denominator=0; if (fabs(value)<1.0e-10) return tryA; integerPart = floor(value); value -= integerPart; tryThis.numerator = tryB.numerator* static_cast (integerPart) + tryA.numerator; tryThis.denominator = tryB.denominator* static_cast (integerPart) + tryA.denominator; tryA = tryB; tryB = tryThis; while (value>1.0e-10 && tryB.denominator <=maxDenominator) { nLoop++; if (nLoop>50) { Rational bad; bad.numerator=-1; bad.denominator=-1; #if CGL_DEBUG>1 printf(" *** bad rational\n"); #endif return bad; } value = 1.0/value; integerPart = floor(value+1.0e-10); value -= integerPart; tryThis.numerator = tryB.numerator* static_cast (integerPart) + tryA.numerator; tryThis.denominator = tryB.denominator* static_cast(integerPart) + tryA.denominator; tryA = tryB; tryB = tryThis; } if (tryB.denominator <= maxDenominator) { #if CGL_DEBUG>1 printf("%d/%d\n",tryB.numerator,tryB.denominator); #endif return tryB; } else { #if CGL_DEBUG>1 printf("%d/%d\n",tryA.numerator,tryA.denominator); #endif return tryA; } } // end copied from CglGomory.cpp void test(double numerator) { auto frac = nearestRational(numerator, 100000); double result = static_cast(frac.numerator) / frac.denominator; std::cout << frac.numerator << " / " << frac.denominator << " = " << result << std::endl; } int main() { test(0.5407407407407234); test(0.8111111111111367); }