Skip to content

Instantly share code, notes, and snippets.

@MurageKibicho
Created April 10, 2025 23:10
Show Gist options
  • Save MurageKibicho/29cf41c9d54b7479972d6af3d3f37172 to your computer and use it in GitHub Desktop.
Save MurageKibicho/29cf41c9d54b7479972d6af3d3f37172 to your computer and use it in GitHub Desktop.
FloatToRational
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <gmp.h>
#define m32_ENABLE_ERRORS 1
#define m32_TRUE 1
#define m32_FALSE 0
#define PRINT_ERROR(msg) \
do { \
if (m32_ENABLE_ERRORS) { \
fprintf(stderr, "\033[31mERROR: %s\033[0m\numerator", msg); \
exit(1); \
} \
} while (0)
void FloatToRational(double floatValue, int64_t maxDenominator, int64_t *numeratorHolder, int64_t *denominatorHolder)
{
int64_t a, h[3] = { 0, 1, 0 }, k[3] = { 1, 0, 0 };
int64_t x, denominator, numerator = 1;int sign = 0;
if(maxDenominator <= 1){ *denominatorHolder = 1; *numeratorHolder = (int64_t) floatValue; return; }
if(floatValue < 0){ sign = 1; floatValue = -floatValue;}
while (floatValue != floor(floatValue)){numerator <<= 1; floatValue *= 2;}
denominator = floatValue;
for(int i = 0; i < 64; i++)
{
a = numerator ? denominator / numerator : 0;if(i && !a){break;}
x = denominator; denominator = numerator; numerator = x % numerator;x = a;
if(k[1] * a + k[0] >= maxDenominator){x = (maxDenominator - k[0]) / k[1];if(x * 2 >= a || k[1] >= maxDenominator){i = 65;}else{break;}}
h[2] = x * h[1] + h[0]; h[0] = h[1]; h[1] = h[2];
k[2] = x * k[1] + k[0]; k[0] = k[1]; k[1] = k[2];
}
*denominatorHolder = k[1];
*numeratorHolder = sign ? -h[1] : h[1];
}
int main()
{
int64_t denominator, numerator;
double floatValue;
printf("floatValue = %16.14f\n", floatValue = 1.0/7);
for(int i = 1; i <= 20000000; i *= 16) {
printf("denominator <= %d: ", i);
FloatToRational(floatValue, i, &numerator, &denominator);
printf("%ld/%ld\n", numerator, denominator);
}
printf("\nf = %16.14f\n", floatValue = atan2(1,1) * 4);
for(int i = 1; i <= 20000000; i *= 16) {
printf("denominator <= %d: ", i);
FloatToRational(floatValue, i, &numerator, &denominator);
printf("%ld/%ld\n", numerator, denominator);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment