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
my ft_printf => 15 octal => 017
original printf => 15 octal => 017
but regarding the negative numbers:
my ft_printf => -15 octal => 0-17
original printf => -15 octal => 037777777761
what should i modify with my function in order for it to print the negative numbers just like the printf does thank you!!!
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);
}
CodePudding user response:
Here is a very simple function to convert number to any base (limited to the number of available digit symbols).
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
After OPs comment:
function which will print signed or unsigned representation of the value depending on the asUnsigned
parameter:
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
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
CodePudding user response:
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
This implies OP is incorrectly getting the argument.
With "%o"
, "%x"
, "%X"
, "%u"
, the corresponding argument is type unsigned
, not int
.
With a proper printf()
, there is no printing of a signed integer with specifiers oxXu
.
Code attempting to pass a negative integer to match a oxXu
results in undefined behavior (UB). A common UB is to treat the signed argument as if it was unsigned.