Programming 版 (精华区)
发信人: JJason (总统~~), 信区: Programming
标 题: [合集]把浮点数转化为分数
发信站: 哈工大紫丁香 (2003年03月10日10:45:36 星期一), 站内信件
────────────────────────────────────────
pamws (书虫) 于 2002年12月22日17:33:33 星期天 说道:
怎么精确的转换呢? 就是说需要最简的形式. C/C++中的浮点数是有误差的, 我对真分数
的转换结果会得到十几位的分子和分母.
e.g.
3.1415926=15707963/5000000
因为15707963和5000000互质,并且相除的结果刚好等于那个分数
但是我的程序结果是
42165742107361281/13421772800000000
────────────────────────────────────────
cccbuilder (建造者) 于 Sun Dec 22 19:55:48 2002) 说道:
你不觉得这两个整数有点大吗!!!
这样很容易溢出的!!!
【 在 pamws (书虫) 的大作中提到: 】
: 怎么精确的转换呢? 就是说需要最简的形式. C/C++中的浮点数是有误差的, 我对真 ..
: 的转换结果会得到十几位的分子和分母.
: e.g.
: 3.1415926=15707963/5000000
: 因为15707963和5000000互质,并且相除的结果刚好等于那个分数
: 但是我的程序结果是
: 42165742107361281/13421772800000000
────────────────────────────────────────
pamws (书虫) 于 2002年12月23日12:50:21 星期一 说道:
谢谢你的提醒, 但是对我来说这里不需要考虑溢出, 给出的数据都是精确的.
如果可能的话请帮助解决我的问题
【 在 cccbuilder (建造者) 的大作中提到: 】
: 你不觉得这两个整数有点大吗!!!
: 这样很容易溢出的!!!
: 【 在 pamws (书虫) 的大作中提到: 】
: : 怎么精确的转换呢? 就是说需要最简的形式. C/C++中的浮点数是有误差的, 我对真 ..
:
: : 的转换结果会得到十几位的分子和分母.
: : e.g.
: : 3.1415926=15707963/5000000
: : 因为15707963和5000000互质,并且相除的结果刚好等于那个分数
: : 但是我的程序结果是
: : 42165742107361281/13421772800000000
────────────────────────────────────────
xceman (辉->雪狼*遥望北方) 于 2002年12月23日13:26:54 星期一 说道:
用的什么算法亚?
【 在 pamws (书虫) 的大作中提到: 】
: 怎么精确的转换呢? 就是说需要最简的形式. C/C++中的浮点数是有误差的, 我对真分数
: 的转换结果会得到十几位的分子和分母.
: e.g.
: 3.1415926=15707963/5000000
: 因为15707963和5000000互质,并且相除的结果刚好等于那个分数
: 但是我的程序结果是
────────────────────────────────────────
JJason (酱牛肉~~想家了:() 于 2002年12月23日13:47:10 星期一 说道:
这种东西只能自己编程实现了
仅仅靠语言是不大可能
【 在 pamws (书虫) 的大作中提到: 】
: 谢谢你的提醒, 但是对我来说这里不需要考虑溢出, 给出的数据都是精确的.
: 如果可能的话请帮助解决我的问题
: 【 在 cccbuilder (建造者) 的大作中提到: 】
: : 你不觉得这两个整数有点大吗!!!
: : 这样很容易溢出的!!!
────────────────────────────────────────
pamws (书虫) 于 2002年12月23日13:59:43 星期一 说道:
好像你没有理解我的问题
e.g.
double n=3.1415927
但是小数点后面没给出的部分并不总是0(是随机的?)
我的问题是如何克服这种情况获得实际的有效数字?
~~~~~~~~~~~~~~
【 在 JJason (酱牛肉~~想家了:() 的大作中提到: 】
: 这种东西只能自己编程实现了
: 仅仅靠语言是不大可能
: 【 在 pamws (书虫) 的大作中提到: 】
: : 谢谢你的提醒, 但是对我来说这里不需要考虑溢出, 给出的数据都是精确的.
: : 如果可能的话请帮助解决我的问题
────────────────────────────────────────
pamws (书虫) 于 2002年12月23日16:24:52 星期一 说道:
:)
我就是这样做的, 但是并不总能得到最简的结果.
比如最开始的那个例子, 昨天和今天用VC调试看到的结果就不一样.
似乎这已经不是语言的问题而是涉及到系统对浮点数的处理了.
anyway, thanks.
【 在 bell (冷冷星光|郁闷中) 的大作中提到: 】
: 比如要转化1.125,那么他等于1.125/1
: 那么对1.125乘以1000变成1125, 1乘以1000等于1000
: 1125和1000找到最大公约数125一除变成9/8就是结果。
: 不知道这么做可不可以。
: 【 在 bell (冷冷星光|郁闷中) 的大作中提到: 】
: : 转化成整数
────────────────────────────────────────
pamws (书虫) 于 2002年12月23日16:53:01 星期一 说道:
// 我的程序(精简版)
// for VC and gcc
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
typedef __int64 i64;
typedef unsigned __int64 u64;
// greatest common divisor
template <class T>
T gcd(T a, T b)
{
if (b==0) return a;
else return gcd(b, a%b);
}
// class fraction
class CFRACT
{
public:
bool neg; // is negative?
i64 nume; // numerator
i64 deno; // denominator
public:
CFRACT(): neg(false), nume(0), deno(1) {};
CFRACT(double n);
};
CFRACT::CFRACT(double n)
{
neg=(n>=0)?false:true;
n=(neg)?(-n):n;
nume=0;
deno=1;
while (n>0) {
n*=10;
nume*=10;
nume+=floor(n);
deno*=10;
n-=floor(n);
}
i64 g=gcd(nume, deno);
nume/=g;
deno/=g;
}
using namespace std;
int main(void)
{
double n=1.125;
CFRACT f(n);
printf("%lf=%c", n, (f.neg)?'-':' ');
printf("%I64d/%I64d\n", f.nume, f.deno);
fflush(stdout);
system("PAUSE");
return 0;
}
【 在 pamws (书虫) 的大作中提到: 】
: :)
: 我就是这样做的, 但是并不总能得到最简的结果.
: 比如最开始的那个例子, 昨天和今天用VC调试看到的结果就不一样.
: 似乎这已经不是语言的问题而是涉及到系统对浮点数的处理了.
: anyway, thanks.
: 【 在 bell (冷冷星光|郁闷中) 的大作中提到: 】
────────────────────────────────────────
Uranus (天王星) 于 Mon Dec 23 18:24:52 2002) 说道:
【 在 pamws (书虫) 的大作中提到: 】
: public:
: bool neg; // is negative?
: i64 nume; // numerator
: i64 deno; // denominator
: public:
: CFRACT(): neg(false), nume(0), deno(1) {};
: CFRACT(double n);
: };
: CFRACT::CFRACT(double n)
: {
: neg=(n>=0)?false:true;
: n=(neg)?(-n):n;
: nume=0;
: deno=1;
: while (n>0) {
^^^^这个地方有问题。不能指望n == 0的情况出现。
: n*=10;
: nume*=10;
: nume+=floor(n);
: deno*=10;
: n-=floor(n);
: }
: i64 g=gcd(nume, deno);
: nume/=g;
: deno/=g;
: }
: using namespace std;
: int main(void)
: {
: double n=1.125;
: CFRACT f(n);
: printf("%lf=%c", n, (f.neg)?'-':' ');
: printf("%I64d/%I64d\n", f.nume, f.deno);
: fflush(stdout);
: system("PAUSE");
: return 0;
: }
: 【 在 pamws (书虫) 的大作中提到: 】
: : :)
: : 我就是这样做的, 但是并不总能得到最简的结果.
: : 比如最开始的那个例子, 昨天和今天用VC调试看到的结果就不一样.
: : 似乎这已经不是语言的问题而是涉及到系统对浮点数的处理了.
: : anyway, thanks.
: : 【 在 bell (冷冷星光|郁闷中) 的大作中提到: 】
────────────────────────────────────────
pamws (书虫) 于 2002年12月23日18:33:48 星期一 说道:
浮点数通常不严格判等于0, 并不是因为它们不能等于0.
作为循环控制是完全安全的,那个循环不会超过20次
因为MSDN指出的绝对值最小浮点数为(float.h)
DBL_EPSILON=2.2204460492503131e–016
n足够小的时候就有n==0成立, 也许不容易理解,
不过试过之后你会发现确实如此 :)
【 在 Uranus (天王星) 的大作中提到: 】
:
:
: 【 在 pamws (书虫) 的大作中提到: 】
: : public:
: : bool neg; // is negative?
: : i64 nume; // numerator
: : i64 deno; // denominator
: : public:
: : CFRACT(): neg(false), nume(0), deno(1) {};
: : CFRACT(double n);
: : };
────────────────────────────────────────
Pomegranate (石榴哥-=|863-05|=-) 于 2002年12月23日19:50:46 星期一 说道:
int euclid(int a, int b)
{
if (b==0) return a; else return euclid(b,a%b);
}
void main()
{
double x=3.1415926;
int a,b=1;
while (x-floor(x)>1e-17) { x*=10; b*=10; }
a=euclid(x,b);
printf("%d %d\n",(int)x/a,b/a);
}
【 在 pamws (书虫) 的大作中提到: 】
: // 我的程序(精简版)
: // for VC and gcc
: #include <stdio.h>
: #include <stdlib.h>
: #include <cmath>
: typedef __int64 i64;
: typedef unsigned __int64 u64;
: // greatest common divisor
: template <class T>
: T gcd(T a, T b)
────────────────────────────────────────
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:204.679毫秒