Is this C function poorly written?

char byte_to_ascii(char value_to_convert, volatile char *converted_value) {

 if (value_to_convert < 10) {
  return (value_to_convert + 48);
 } else {
  char a = value_to_convert / 10;
  double x = fmod((double)value_to_convert, 10.0);
  char b = (char)x;
  a = a + 48;
  b = b + 48;
  *converted_value = a;
  *(converted_value+1) = b;
  return 0;
 }
}

The purpose of this function is to take an unsigned char value from 0 to 99 and return either the ascii equivalent if it is 0-9, or manipulate a small global array of characters that can be referenced from the calling code by the subsequent completion function.

I ask this question because two compilers from the same provider interpret this code differently.

This code was written as a way of analyzing pairs of bytes transmitted through RS485 into strings that can be easily passed to the send-lcd-string function.

This code is written for the PIC18 architecture (8 bits uC).

, / , , , , -.

, , , , - .

.

+5
11

. , , .

, , /.

q =p/10;
r = p - q*10;
+4

- PIC. - . -ascii char -? -, ?

, 10, 17 , . , , , .

61:                         q = d2 / 10;
 01520  90482E     mov.b [0x001c+10],0x0000
 01522  FB8000     ze 0x0000,0x0000
 01524  2000A2     mov.w #0xa,0x0004
 01526  090011     repeat #17
 01528  D88002     div.uw 0x0000,0x0004
 0152A  984F00     mov.b 0x0000,[0x001c+8]

- , , , Symbolic ( ) , . ( ), (ish) _reset.

223 001BC _ floatsisf, (_fpack, _divsf3 ..) _funpack, 535 0042C . (42C-1BC = 0x270 =) 624 , , 2k , .

, , ​​ 2.

-, , , ( ), ascii? ( ).

+7

, , :

char byte_to_ascii(char value_to_convert, volatile char *converted_value)
{
 if (value_to_convert < 10) {
  return value_to_convert + '0';
 } else {
  converted_value[0] = (value_to_convert / 10) + '0';
  converted_value[1] = (value_to_convert % 10) + '0';
  return 0;
 }
}
+4

, fmod , %? , . , , for. , - , , .

, , , , sleep for.

, ? " "? , char * , , , C. ?

+3

, , .

, b , MOD roll-your-own:

char a = value_to_convert / 10;
char b = value_to_convert - (10 * a);

/ float -, .

, "" "" "char", ( ). , , , char (, , !). , - / , char .

8- ( ), .

, .

+2

, , , 0-9 10-99. , : .

+1

10 .

. .

unsigned char divide_by_10 (unsigned char value)
{
  unsigned char q;
  q = (value>>1) + (value>>2);
  q += (q>>4);
  q >>= 3;
  value -= (q<<3)+q+q;
  return q+((value+6)>>4);
}

Cheers, Nils

+1

, .

convert_value , , ?

0

PIC .

Windows, mod (. ).

char byte_to_ascii(char value_to_convert, volatile char *converted_value) {

 if (value_to_convert < 10) {
  return (value_to_convert + 48);
 } else {
  char a = value_to_convert / 10;  
  char b = value_TO_convert%10;
  a = a + 48;
  b = b + 48;
  *converted_value = a;
  *(converted_value+1) = b;
  return 0;
 }
}
0

, , :
char byte_to_ascii(char value_to_convert, volatile char *converted_value) {

if (value_to_convert < 10) {
    return (value_to_convert + 48);
} else {
char a = value_to_convert / 10;
double x = fmod((double)value_to_convert, 10.0);
char b = (char)x;
a = a + 48;
b = b + 48;
*converted_value = a;
*(converted_value+1) = b;
return 0;

}
}
  :

ASCII, , .. '@' 0x40.
fmode.

:
// 8-
char value;
char largeValue;
value = value_to_convert / 100;
value += '0';
converted_value[0] = value;
largeValue = value_to_convert - value * 100;
value = largeValue / 10; value += '0';
converted_value[1] = value;
largeValue = largeValue - value * 10; value += '0';
converted_value[2] = value;
converted_value[3] = '\0'; // Null terminator.

3 , . , . , .

, :
 value = (value == 0)? '': + '0';

0

Just to be nitwitt, but several operators returnfrom the same function can be considered bad (MISRA).

In addition, some of the discussions above are at the limit of perestroika optimizations. Some tasks should be left to the compiler. However, in such a minimalistic embedded environment, these tricks can still be valid.

0
source

All Articles