简体   繁体   English

如何在没有任何帮助功能的情况下将负十进制数转换为八进制基数

[英]How to convert a negative decimal number to octal base without any helping funtions

I'm implementing the printf function and now am stuck at the conversion of the negative base 10 number into a base 8 octal number, below i placed the piece of code which is working just fine in regard to converting a positive decimal number to octal just like the printf我正在实现 printf function 并且现在被困在将负基数 10 数字转换为基数 8 八进制数,下面我放置了一段代码,它在将正十进制数转换为八进制时工作得很好像 printf

my ft_printf => 15 octal => 017我的 ft_printf => 15 八进制 => 017

original printf => 15 octal => 017原装 printf => 15 八进制 => 017

but regarding the negative numbers:但关于负数:

my ft_printf => -15 octal => 0-17我的 ft_printf => -15 八进制 => 0-17

original printf => -15 octal => 037777777761原始 printf => -15 八进制 => 037777777761

what should i modify with my function in order for it to print the negative numbers just like the printf does thank you!!!我应该用我的 function 修改什么,以便它像 printf 一样打印负数谢谢!

void    process_octal(unsigned int n)
{
    char    *str;
    int     oct = 0;
    int     rem = 0;
    int     place = 1;

    while (n)
    {
        rem = n % 8;
        oct = oct + rem * place;
        n = n / 8;
        place = place * 10;    
    }
    str = ft_itoa(oct);
    ft_putstr_fd(str, 1);
}

Here is a very simple function to convert number to any base (limited to the number of available digit symbols).这是一个非常简单的 function 将数字转换为任何基数(限于可用数字符号的数量)。

char *reverse(char *ptr, size_t length)
{
    char *str = ptr;
    if(ptr && length)
    {
        char *end = ptr + length - 1;
        while(end > str)
        {
            char tmp = *str;
            *str++ = *end;
            *end-- = tmp;
        }
    }
    return ptr;
}


char *convert(char *buff, long long val, unsigned base)
{
    const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZ";
    int negative = val < 0;
    size_t count = 0;

    if(base < 2 || base > sizeof(digits) - 1) return NULL;

    do
    {
        buff[count++] = digits[abs(val % base)];
        val /= base;
    }while(val);
    if(negative) buff[count++] = '-';
    buff[count] = 0;
    return reverse(buff, count);
    
}

https://godbolt.org/z/Wz15h4x41 https://godbolt.org/z/Wz15h4x41

After OPs comment: OP评论后:

function which will print signed or unsigned representation of the value depending on the asUnsigned parameter: function 将根据asUnsigned参数打印值的有符号或无符号表示:

char *convert(char *buff, long long val, unsigned base, int asUnsigned)
{
    const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVXYZ";
    int negative = val < 0;
    size_t count = 0;

    if(base < 2 || base > sizeof(digits) - 1) return NULL;

    do
    {
        buff[count++] = digits[asUnsigned ? ((unsigned)val) % base : abs(val % base)];
        val = (asUnsigned ? (unsigned)val : val) / base;
    }while(val);
    if(!asUnsigned && negative) buff[count++] = '-';
    buff[count] = 0;
    return reverse(buff, count);
    
}

https://godbolt.org/z/MdMGerTTs https://godbolt.org/z/MdMGerTTs

int main(void) {
    char str[32];
    printf("%s\n", convert(str, -15, 8, 1));  
    printf("%s\n", convert(str, -15, 8, 0));  

}

Result:结果:

37777777761
-17

I'm implementing the printf function and now am stuck at the conversion of the negative base 10 number into a base 8 octal number我正在实施 printf function ,现在卡在将负基数 10 转换为基数 8 八进制数

This implies OP is incorrectly getting the argument.这意味着 OP 错误地获得了论点。

With "%o" , "%x" , "%X" , "%u" , the corresponding argument is type unsigned , not int .对于"%o""%x""%X""%u" ,对应的参数是unsigned类型,而不是int

With a proper printf() , there is no printing of a signed integer with specifiers oxXu .使用适当的printf() ,不会打印带有说明符oxXu签名integer 。

Code attempting to pass a negative integer to match a oxXu results in undefined behavior (UB).尝试传递否定的 integer 以匹配oxXu的代码会导致未定义的行为(UB)。 A common UB is to treat the signed argument as if it was unsigned .一个常见的 UB 是将带符号的参数视为无符号的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM