- 论坛徽章:
- 2
|
回复 1# CU达人
1. 循环节一定存在
相同余数会产生相同后续序列,而余数的取值范围是有限的: [0,分母) 。
一位一位取就是了……
直到遇见相同余数,或余数为0。
2. 有尽小数
只要除数的质因子中只有2与5,就能除尽。
可通过这个判断是否需要"()"记号。
3. 进制
虽然最终是按十进制输出,但内部进制不一定必须是十进制或字符。
内部进制大一些可以减少一些计算, 输出时注意 leading 与 tailing 零就行。
只是对本例子来说作用不明显, 还会加大找循环节的难度……
所以代码中只对有尽小数使用……
- #include <stdio.h>
- #include <stdlib.h>
- int terminating_decimal(int divisor)
- {
- while (divisor%2u==0) divisor/=2u;
- while (divisor%5u==0) divisor/=5u;
- return divisor==1;
- }
- int main(int argc, char* argv[])
- {
- int dividend,divisor,remainder;
- dividend = argc>1? atoi(argv[1]): 1;
- divisor = argc>2? atoi(argv[2]): 1;
- if (dividend<0 || divisor<=0) {
- fprintf(stderr, "for simplification supports positive only\n" );
- return EXIT_FAILURE;
- }
- printf("%d", dividend/divisor);
- remainder = dividend%divisor;
- if (!remainder)
- return 0;
- printf(".");
- if (!terminating_decimal(divisor))
- {
- char* digits = (char*)malloc(divisor);
- int i = 0, j;
- int* met = (int*)calloc(divisor,sizeof(int));
- do {
- int dividend = remainder*10u;
- int quotient = dividend/divisor;
- digits[i] = quotient+'0';
- met[remainder] = ++i;
- remainder = dividend % divisor;
- } while (!met[remainder]);
- j = met[remainder]-1;
- printf("%.*s(%.*s)", j, digits, i-j, digits+j);
- free(met);
- free(digits);
- }
- else
- {
- #define RADIX 100u
- #define EXPONENT 2
- #define STR(x) STR_(x)
- #define STR_(x) #x
- int quotient,i;
- for (; dividend = remainder*RADIX
- , quotient = dividend/divisor
- , remainder = dividend%divisor
- , remainder
- ; printf("%0" STR(EXPONENT) "d", quotient) ) ;
- for (i=RADIX/10; quotient; quotient%=i, i/=10u)
- putchar(quotient/i+'0');
- }
- printf("\n");
- return 0;
- }
复制代码 最后附加一份测试代码
- #!/usr/bin/env python
- import sys
- import re
- from fractions import Fraction
- p = re.compile(r'[ ]*([0-9]*)\.?([0-9]*)(\(([0-9]*)\))?')
- for line in sys.stdin :
- m = p.match(line)
- i,f,_,r = m.groups()
- w = 10**len(f)
- result = (int(i) if i else 0) \
- + (Fraction(int(f),w) if f else 0) \
- + (Fraction(int(r),10**len(r)-1)/w if r else 0)
- expect = line[m.end():].strip()
- expect = Fraction(expect) if expect else result
- print line[:m.end()],result
- if expect!=result : print >>sys.stderr, line[:m.end()],expect,result
复制代码
- for ((i=1;i<=1212;++i)) do echo $(fraction2decimal 1 $i) 1/$i; done | decimal2fraction.py >/dev/null
复制代码 |
|