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毫秒