仅使用C中的系统调用打印浮点值

时间:2014-09-03 11:43:44

标签: c floating-point double system-calls

我正在尝试编写一个C程序,以人类可读的格式(即KB,MB,GB等)打印文件大小。输入是以字节为单位的文件大小。问题是这只能使用系统调用和NO库调用来完成。

我已经编写了一个函数,它将正整数转换为字符串,然后使用write()系统调用打印它。我对如何使用write()打印十进制值一无所知,因为转换后的文件大小(KB或MB或GB)可能是小数。(例如:4.0K,5.6G等)。

此外,是否可以将精度限制在某个固定长度(比如2个小数位)??

3 个答案:

答案 0 :(得分:2)

对于很多情况,您可以像对整数一样转换浮点数。首先通过将float转换为int并将其转换为string来转换整数部分。然后附加小数点,从原始浮点数中减去整数,乘以所需的精度并执行相同的操作(如果需要,使用前导零)。

从概念上讲,你可以这样做:

int integerPart = myFloat;
int decimalPart = (myFloat - integerPart) * 1000; // for three decimal places
char* stringRep = intToStringNoLeadingZeros(integerPart);
appendChar(stringRep, '.');
appendIntToStringWithLeadingZeros(stringRep, decimalPart);

这个不起作用浮点数大于最大可能整数,如果需要大量小数位,将失去精度。但对于常见情况,这是一种快速的方法。如果你想让它适用于alle case,你必须编写直接解释浮点格式的代码,但我想这会有更多的工作。

答案 1 :(得分:0)

我认为这是你的解决方案:

#include <unistd.h>

void printInt(int n) {
  char c;

  if (!n)
    return ;
  printInt(n/10);
  c = n % 10 + '0';
  write(1, &c, 1);
}

void    _printInt(int n) {
  if (!n)
    write(1, "0", 1);
  else
    printInt(n);
}

void    _printD(double n, int K) {
  _printInt((int)n);
  n -= (int)n;
  if (!n && !K)
    return ;
  write(1, ".", 1);
  while ((!n && K) || K) {
    _printInt((int)(n*10));
    n=n*10-((int)(n*10));
    K--;
  }
}

int main() {
  _printD(10.543, 2);
  return 0;
}

如果您需要一些建议,请说出来!

答案 2 :(得分:0)

void printNum(unsigned n){
    char nums[4];
    int i;
    if(n == 0)
        write(1, "0", 1);
    for(i=4; n ;){
        nums[--i] = '0' + n % 10;
        n /= 10;
    }
    write(1, &nums[i], 4 - i);
}

void printStr(const char *s){
    while(*s)
        write(1, s++, 1);
}

void printSizeWithUnit(unsigned long long n){
    static char *unit[] = { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
    unsigned long long v = n;
    int u_no = 0;
    while(n >= 1024){
        v = (n * 10+512) / 1024;
        n /= 1024;
        ++u_no;
    }
    if(v>=1000){
        v = (n * 10+512) / 1024;
        ++u_no;
    }
    if(u_no==0){
        printNum((unsigned)v);
        printStr(unit[u_no]);
        printStr("\n");
    } else {
        printNum((unsigned)v/10);
        printStr(".");
        printNum((unsigned)v%10);
        printStr(unit[u_no]);
        printStr("\n");
    }
}

int main(void){
    printSizeWithUnit(777ULL);
    printSizeWithUnit((unsigned long long)(5.56*1024*1024));
    printSizeWithUnit(1024*777ULL);
    printSizeWithUnit(1024*1024*777ULL);
    return 0;
}