2010-03-17 2 views
1

Учитывая 2 32bit Интс iMSB и ILSBC++ долго долго манипуляция

int iMSB = 12345678; // Most Significant Bits of file size in Bytes 
int iLSB = 87654321; // Least Significant Bits of file size in Bytes 

длинная длинная форма будет ...

// Always positive so use 31 bts 
long long full_size = ((long long)iMSB << 31); 
      full_size += (long long)(iLSB); 

Теперь ..

мне не нужно, что (точное количество байтов), поэтому, как я могу преобразовать размер файла в MiBytes в 3 десятичных знака и преобразовать в строку ...

пробовал это ...

long double file_size_megs = file_size_bytes/(1024 * 1024); 
char strNumber[20]; 
sprintf(strNumber, "%ld", file_size_megs); 

... но dosen't, похоже, работает.

i.e. 1234567899878Bytes = 1177375.698MiB ??

+0

Сколько битов данных есть в ILSB? Эта информация необходима для правильного смещения значения iMSB в нужное место. Надеюсь, вы также поймете, что вы инициализировали переменные с десятичными значениями, а после смещения бит часть MSB - это нечто совершенно другое. – Tronic

+1

Этот сдвиг 31 бит вместо 32 кажется ужасно подозрительным. – OldFart

+0

@OldFart - целые числа подписаны, поэтому только 31 бит используется в том, что возвращается и помещается в iMSB и iLSB. Это верхние 31 бит и нижние 31 бит размера. – Krakkos

ответ

9

Вы неправильно понимаете, как работает операция. Ваше вычисление должно быть:

// Always use 32 bits 
long long full_size = ((long long)iMSB << 32); 
      full_size += (unsigned long long)(iLSB); 

Однако, сочетание 12345678, 87654321 является не 1234567887654321; это 53024283344601009.

Затем, когда вы делаете

long double file_size_megs = file_size_bytes/(1024 * 1024); 
char strNumber[20]; 
sprintf(strNumber, "%ld", file_size_megs); 

Вы принимаете (что формат с плавающей точкой) в long double и печать с %ld, которая является формат целое. Что вы имели в виду был:

long long file_size_megs = file_size_bytes/(1024 * 1024); 
char strNumber[20]; 
sprintf(strNumber, "%lld", file_size_megs); 

Альтернативой вычислить только размер файла в мегабайтах:

long long file_size_megs = ((long long)iMSB << (32 - 20)) + ((unsigned)iLSB >> 20); 
+3

+1 за храбрость, чтобы ответить на такой заданный вопрос. Значения, которые подписываются, могут представлять сложность. Я бы рекомендовал просто сделать все целые переменные без знака, чтобы избежать таких проблем. – Tronic

+0

этот sprintfs длинный длинный, как длинный, используйте% lld. – nos

+0

Так как это отмечено C++, в любом случае следует использовать потоки вместо sprintf (и избегать этих неприятных ошибок строки форматирования). – Tronic

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