2014-01-21 5 views
1

Я работаю над небольшим проектом электроники дома с помощью микроконтроллера PIC 18F, который я программирую с помощью HiTech C18, который будет использоваться для цифрового управления электропитанием скамьи.C, разделить число с плавающей запятой на отдельные цифры

Я столкнулся с проблемой, которая заключается в том, что у меня есть число с плавающей запятой в переменной, например, например, 12.34, и нужно разбить ее на 4 переменных, удерживающих каждый отдельный номер, поэтому я получаю Char1 = 1, Char2 = 2 и т. д. и т. д. для отображения на 4-сегментном семисегментном светодиодном дисплее. Число всегда будет округлено до 2 знаков после запятой, поэтому не должно быть необходимости отслеживать местоположение десятичной точки.

Я стараюсь избегать любого округления, где возможно выше 2 знаков после запятой, поскольку дисплеи дают измерения напряжения/тока, и это повлияет на точность показаний.

Любые советы о том, как получить этот раскол, будут очень признательны.

Благодаря

+2

Почему бы просто не использовать целое число и назвать его centiVolts? Ответы ниже все в порядке, но я бы подумал, что было бы проще превратить целое число centiVolt в float, если вам когда-нибудь понадобится, чем постоянно продолжать его расстраивать. –

+0

Это не перешло мне в голову, я мог бы умножить значение на 100, а затем, поскольку положение десятичной точки контролируется отдельно, я могу просто правильно позиционировать его, чтобы дать правильное считывание. В этом случае обычный способ получения каждой цифры. –

ответ

3

Используйте sprintf, чтобы поместить значение в массив символов. И затем выберите цифры оттуда.

Вы можете преобразовать значение с плавающей запятой непосредственно в текст. Или вы можете умножить на 100, обрезать или округлить до int, а затем преобразовать их в текст.

+0

Спасибо Дэвиду, я собираюсь попытаться спуститься по пути умножения на 100, а затем просто позиционировать десятичную точку. Я хотел бы избежать преобразования текста, где это возможно, по мере передачи данных и шины I2C, и мне потребуется позже преобразовать его в шестнадцатеричный. –

+1

Преобразование в десятичные разряды неотличимо от преобразования в десятичный текст –

3

Преобразовать в int, а затем в строку.

float x; 
int i = x*100; 
// or i = x*100.0f + 0.5f is round to nearest desired. 
if ((i < 0) || (i > 9999)) Handle_RangeProblem(); 
char buf[5]; 
sprintf(buf, "%04d", i); 

В встроенных приложений, многие компиляторы используют строку фиксированного формата, чтобы определить, какие будут необходимы части большогоprintf() кода. Если код готов, используя "%f", где нет, то прямо sprintf("%f") здесь не проблема. В противном случае использование %04d" может привести к значительной экономии пространства.

0

Учитывая заявленную стабильность вашей десятичной точки: просто sprintf() поплавка в буфер с соответствующим спецификатор формата, то у вас есть 4 значения в строке легко добытой в то, что когда-либо type вы их должны быть в ...

Пример

float num = 12.1234456; 
char buf[6]; 

int main(void) 
{ 
    char a[2], b[2], c[2], d[2]; 
    int x, y, z, w;  

    sprintf(buf, "%0.2f", num);//capture numeric into string 
    //split string into individual values (null terminate) 
    a[0] = buf[0]; a[1]=0; 
    b[0] = buf[1]; b[1]=0; 
    //skip decimal point 
    c[0] = buf[3]; c[1]=0; 
    d[0] = buf[4]; d[1]=0; 

    //convert back into numeric discretes if necessary 
    x = atoi(a); 
    y = atoi(b); 
    z = atoi(c); 
    w = atoi(d); 
} 

Есть, конечно, более элегантные способы, но это будет работать ...

+0

Чтобы справиться со значениями, такими как 1.23, предложите «% 05.2f», чтобы избежать «1.23» и получить «01.23». – chux

1

Номера с плавающей запятой хранятся в двоичном формате, состоящем из знакового бита, мантиссы и экспоненты. Число с плавающей запятой может не точно соответствовать заданному десятичному представлению (из-за разности базы-10 для десятичного числа из базы с плавающей запятой базы-2). Преобразование числа с плавающей запятой в десятичное представление является проблемой, часто назначаемой в начальных курсах программирования.

Поскольку вас интересуют только два десятичных знака и ограниченный диапазон значений, вы можете использовать фиксированное представление вашего значения. Это уменьшит проблему от преобразования числа с плавающей точкой в ​​десятичное в преобразование целого числа в десятичное.

long 
longround(float f) 
{ 
    long x; 
    x = (long)((f*100)+.5); //round least significant digit 
    return(x); 
} 

char* 
long2char(char ca[], long x) 
{ 
    int pos=0; 
    char sign = '+'; 
    ca[pos] = '0'; 
    long v = x; 
    if(v<0) { 
     sign = '-'; 
     v = -v; 
    } 
    for(pos=0; v>0; ++pos) 
    { 
     ca[pos] = (v%10)+'0'; 
     v = v/10; 
    } 
    ca[pos++] = sign; 
    ca[pos] = '\0'; //null-terminate char array 
    //reverse string - left as exercise for OP 
    return(ca); 
} 

Если у вас есть проблема, где наибольшее значение может превысить диапазон значений, поддерживаемых длинное целое число в вашей системе, то вы должны изменить выше решение.

+0

f * 100, затем круглый. – ChuckCottrill

+0

Да. Согласовано. 0,5 – ChuckCottrill

Смежные вопросы