Ошибка побитовой операции с long long pic32

Я работаю с контроллером pic32mx и использую компилятор C32 toolsuite v2.02 и MPLAB-X IDE v 3.05. Я использую побитовую операцию с длинной длинной переменной, но получаю ошибочный результат.

int main()

{

    long long data0, data1=0;

    data0 = 489631651402;
    data1 = data0 & 0x0FFFFFFFFFF;

    printf("%llu\n%llu\n", data0, data1 );

    return 0;
}

ВЫХОД:

    489631651402

    492260348528

По расчетам этот результат ошибочен. data0 и data1 должны быть равны.

Пожалуйста, предложите мне лучший способ для этой операции. если в приведенной выше процедуре есть какая-либо ошибка, предложите правильный путь.


person ajay vachhani    schedule 08.04.2016    source источник
comment
Вы смотрели на сгенерированный ассемблерный код?   -  person Jabberwocky    schedule 08.04.2016
comment
Значит, число становится больше, когда побитовое — и оно с константой? Хм... Обычно это не очень возможно. Я предлагаю вам перепроверить это, а также почему бы не печатать числа в шестнадцатеричном формате, чтобы сделать их немного более понятными? Плюс то, что Иоахим сказал в своем удаленном ответе, не знаю, почему этого нет.   -  person unwind    schedule 08.04.2016
comment
Единственная проблема, которую я вижу в этом коде, заключается в использовании спецификатора %llu со значениями со знаком. Я сомневаюсь, что это вызовет эту ошибку.   -  person interjay    schedule 08.04.2016
comment
Пожалуйста, проверьте этот microchip.com/forums/m488183.aspx, я не уверен, что эта проблема связана (мало ли что с C32), но попробовать стоит...   -  person Darko Djuric    schedule 08.04.2016
comment
Кажется, что компилятор C32 поддерживает 64-битные типы в лучшем случае ненадежно. Прежде всего, это расширение, прикрепленное к компилятору, в основном поддерживающее только C90 (как сказано в ветке форума, на которую ссылается @DarkoDjuric); Во-вторых, компилятор должен генерировать весь код для обработки 64-битных типов и 64-битной арифметики, поскольку ЦП изначально не поддерживает это, поэтому возможно, что вы нашли ошибку в их компиляторе для обработки 64-битных целочисленных типов.   -  person Some programmer dude    schedule 08.04.2016
comment
Я согласен с вами в этом - может быть, стоит попытаться обозначить константу с помощью LL, чтобы помочь компилятору увидеть, что это константа long long?   -  person tofro    schedule 08.04.2016
comment
Попахивает ошибкой компилятора, когда компилятор выбирает неправильный тип для литералов. У MPLAB вообще очень плохая репутация.   -  person Lundin    schedule 08.04.2016
comment
Также может быть полезно распечатать значение константы - как непосредственно, так и после присвоения только константы переменной long long.   -  person Andrew Henle    schedule 08.04.2016
comment
Совершенно не связано с проблемой и не поможет: я считаю хорошей практикой заполнять шестнадцатеричные константы, используемые в качестве масок, начальными нулями до их максимальной степени. Это облегчает просмотр того, что на самом деле происходит, и позволяет избежать путаницы, как в одном из (неправильный ) ответы ниже. Люди могут (в лучшем случае) реализовать ~ 6 F подряд   -  person tofro    schedule 08.04.2016
comment
Я настоятельно рекомендую перейти на XC32 (новая версия компилятора Microchip), так как C32 не поддерживается как минимум два года... также есть MplabX v3.26.   -  person Darko Djuric    schedule 08.04.2016


Ответы (1)


Используйте ULLONG_MAX в качестве константы, если вам нужна маска для всех битов. Используйте 0x0FFFFFFFFFFLL, если вам нужно замаскировать только эти 48 бит.

person GMichael    schedule 08.04.2016
comment
ULLONG_MAX всегда больше, чем 0x0FFFFFFFFFF. И его значение не обязательно будет равно чему-либо (есть только нижняя граница), так что в любом случае не стоит его использовать. - person interjay; 08.04.2016
comment
Объект, который подвергался побитовому И, имеет тип long long. - person GMichael; 08.04.2016
comment
Я знаю, что да, но это не объясняет, почему вы считаете ULLONG_MAX хорошей заменой 0x0FFFFFFFFFF. - person interjay; 08.04.2016
comment
@interjay Ты уверен? В тексте используется слово величина: Их значения, определенные реализацией, должны быть равны или больше по величине (абсолютное значение) показанным с тем же знаком. Разве это не указывает на степень 2 -1 ? - person 2501; 08.04.2016
comment
Поскольку мы не знаем цели этого побитового И, и вы, и я можем быть правы. я отредактирую ответ - person GMichael; 08.04.2016
comment
@ 2501 Я ничего не говорил о степени двойки, поэтому не знаю, о чем вы говорите. Этот ответ неверен, потому что исходный код использовал 0x0FFFFFFFFFF, а ULLONG_MAX по крайней мере 0xFFFFFFFFFFFFFFFF. Кроме того, нет никакого смысла использовать AND с ULLONG_MAX, потому что это никогда не изменит число. - person interjay; 08.04.2016
comment
@interjay Я имел в виду это: И его значение не обязательно будет равно чему-либо (есть только нижняя граница), - person 2501; 08.04.2016
comment
@ 2501 Под этим я имел в виду только то, что вы не должны использовать ULLONG_MAX, если вам действительно нужно конкретное значение, потому что его значение может различаться в разных реализациях. - person interjay; 08.04.2016
comment
@interjay Да, я знаю, что ты имеешь в виду. Я задала вопрос. Позвольте мне повторить: разве стандарт C не гарантирует, что максимальное значение будет в форме: 2^n-1, а не какое-то произвольное значение? - person 2501; 08.04.2016
comment
@interjay А, я нашел: 6.2.6.2, стр. 1:. Максимальное значение должно быть в форме 2^n-1. - person 2501; 08.04.2016
comment
@ 2501 Да, вероятно, это так (по крайней мере, для значений без знака). Но не имеет отношения к тому, что я сказал выше. - person interjay; 08.04.2016