2016-09-14 2 views
-3

Я борюсь с действительно странной ситуацией, которую я не могу объяснить.
В принципе, я не понимаю, почему результаты модуля или деления между двумя шестнадцатеричными числами неверны (я использую C).Странное поведение при делении шестнадцатеричных чисел

У меня есть переменная time которая является 32bit unsigned int и инициализируется в 0, а затем другие два 32bit unsigned ints, div и res, как инициализируется 0 тоже.

if (time > 0x1388) { 
    div = time/0x1388; 
    res = time - (0x1388 * div); 
} 

Этот фрагмент кода должен действовать в качестве оператора модуль между time и 0x1388. Time - переменная, которая увеличивается по всей моей программе, и когда ее значение больше, чем 0x1388, мне нужно, чтобы его остаток выполнял другие вычисления.

Это пример ошибочной расчетной величины. Предположим, что time составляет 0x1770, что больше 0x1388. Разделение между 0x1770 и 0x1388 должно быть 0x1 (div) с напоминанием о 0x3E8 (res). Проблема в том, что после выполнения этого кода div всегда 0x0FFFFF вместо 0x1 и res получает действительно странное значение.

Я уже пытался использовать модуль, но результат тот же. Может кто-нибудь объяснить мне, что происходит?
Возможно, это связано с тем, что я использую unsigned ints? Если да, можете ли вы рассказать мне, какие операции мне нужно соблюдать при использовании unsigned ints?

EDIT: Попытка добавить еще какой-то код ...
file1.c

unsigned int res = 0, div = 0, time = 0; // global variables 
unsigned int valueChecker() { 
    if (time > 0x1388) { 
     div = time/0x1388; 
     res = time - (0x1388 * div); 
    } 
    return res; 
} 

Эта функция вызывается периодически по истечении определенного промежутка времени

fileB.c

extern unsigned int time; 

void calculate() { 
    // do some stuff 
    time += getHEXTime(); // this function has been supplied and return time as an HEX number 
    // do other stuff 
} 

Эта функция вызывается главным образом несколькими раз, между другими вычислениями (которая не включает time, div или res).

Я был бы так благодарен, если кто-то может мне помочь!

+2

Не могли бы вы опубликовать [Минимальный, * Полный * и Подтверждаемый пример] (http://stackoverflow.com/help/mcve)? – MikeCAT

+2

Стандартная библиотека C имеет функции 'time' и' div', поэтому моя первая попытка будет использовать другие имена, не зная, будет ли она работать. – MikeCAT

+0

Спасибо за ваши комментарии ... Я не использую имена времени и div var, и я не думаю, что есть конфликты, потому что я не использую стандартную библиотеку C. Это просто голой C-код, который должен быть выполнен на эмуляторе ARM. – matteodv

ответ

1

Используя следующую программу, я получаю хороший результат:

#include <stdio.h> 

unsigned int res = 0, div = 0, time = 0x1300; // global variables 
unsigned int valueChecker() { 
    if (time > 0x1388) { 
     div = time/0x1388; 
     printf("Div: %u\n", div); 
     res = time - (0x1388 * div); 
     printf("Mod: %u\n", res); 
    } 
    return res; 
} 

int main(void) { 
    while(time < 0x1390) 
    { 
     time += 1; 
     valueChecker(); 
    } 
    return 0; 
} 

Выход:

Div: 1 
Mod: 1 
Div: 1 
Mod: 2 
Div: 1 
Mod: 3 
Div: 1 
Mod: 4 
Div: 1 
Mod: 5 
Div: 1 
Mod: 6 
Div: 1 
Mod: 7 
Div: 1 
Mod: 8 

Это означает, что проблема, скорее всего, с extern unsigned int time. Чтобы попытаться решить эту проблему, выполните следующие действия:

Убедитесь, что ваши внутренние Глобалы являются declaired в static поэтому никакие другие модули не могут случайно изменить их:

static unsigned int res = 0; 
static unsigned int div = 0; 

Убедитесь, что все символы мульти-блок имеет очень очень уникальное имя, на всякий случай:

unsigned int global_hexTime = 0; 

Когда я следующее:

#include <stdio.h> 
#include <stdlib.h> 

extern unsigned int time; 
/* i had to rename div because it was already in stdlib.h! */ 
static unsigned int res = 0, divisor = 0; // global variables 
unsigned int valueChecker() { 
    if (time > 0x1388) { 
     divisor = time/0x1388; 
     printf("Div: %u\n", divisor); 
     res = time - (0x1388 * divisor); 
     printf("Mod: %u\n", res); 
    } 
    return res; 
} 

int main(void) { 
    int i = 0; 
    while(i < 100) 
    { 
     i += 1; 
     valueChecker(); 
    } 
    return 0; 
} 

Я получаю очень плохой выход:

Div: 510868 
Mod: 863 
Div: 510868 
Mod: 863 
Div: 510868 
Mod: 863 
Div: 510868 
... 

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

+0

В примере с «плохим», я думаю, проблема связана с тем, что формального определения нет (в отличие от объявления) глобальной переменной 'time', поэтому на самом деле функция системной библиотеки' time' предоставляет значение. И вы не можете изменить расположение функции, так что ... все странно. Когда вы явно определяете переменную 'time', вы получаете нормальное поведение. –

+0

@JonathanLeffler Это верно. В моих примерах GCC с переменной 'time' я получил нормальное поведение. Но я думал, что это стоит упомянуть, так как я не знаю, какова его среда или как он компилирует/связывает свои модули. Я не могу думать ни о какой другой причине, кроме столкновений с символами в его программе, которая покажет поведение, которое он описывает из примеров. – Serdalis

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