Created
April 10, 2025 23:10
-
-
Save MurageKibicho/29cf41c9d54b7479972d6af3d3f37172 to your computer and use it in GitHub Desktop.
FloatToRational
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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