LINUX.ORG.RU

разъясните,пожалуйста,как происходит вычисление


0

1

скорректировал сам файл test.c:

#include <stdio.h>
#include <stdint.h>

int main(void) {
	uint32_t a;
	uint64_t b,c,d;
	a=1149952;
	printf("a=%ld\n",a);
	b=(a*4)/1024;
	c=(a*4096)>>20;
	d=(a*4096)/(1024*1024);
	printf("b=%lld c=%lld d=%lld\n",b,c,d);
	return 0;
}
компиллирую и запусаю в 32хбитной системе:
$ gcc test.c  -o test
$ ./test 
a=1149952
b=4492 c=396 d=396
почемы вфчисляется так?



Последнее исправление: wikaka (всего исправлений: 1)
Ответ на: переполнения от yoghurt

да оно и понятно, непонятно в каком месте

wikaka
() автор топика
Ответ на: комментарий от wikaka

> этот факт отражен в коде

этот факт __не должен__ быть отражен в коде, ты пишешь платформенно-зависимый код, а потом удивляешься

aho
()

В таких случаях лучше использовать типы из stdint.h, чтоб было платформо-независимо.

Kosyak ★★★★
()
Ответ на: комментарий от aho

для моделей LLP64 & IL32LLP64 & P64 не разный (64 битные WINDOWS) для моделей LP64 & I32LP64 разный (64 битные UNIX)

anonymous
()
Ответ на: комментарий от aho

а вот «unsigned long», который я процитировал, - для 32 и 64 бита уже разный

для моделей LLP64 & IL32LLP64 & P64 не разный (64 битные WINDOWS) для моделей LP64 & I32LP64 разный (64 битные UNIX)

anonymous
()

> почемы вфчисляется так?

Потому что такие формулы. Нет?

anonymous
()
Ответ на: комментарий от anonymous

char(1) short(2) int(4) long long(8) как были так и остаются при переносе с 32 на 64 бита меняется только размер long в зависимости от системы в венде его оставили 32 битным а на лине подняли до 64 бит его лучше не юзать вдруг программа потом захочет перенестись беда беда

anonymous
()
Ответ на: комментарий от anonymous

в свете этого указатели можно хранить только в long long или в резиновых типах size_t ptrdiff_t intptr_t

anonymous
()
Ответ на: комментарий от anonymous
main()
{
        long blah;

        (void) foo(&blah);

        printf("%ld\n", blah);
}

.... different file ....

foo(int *bar)
{
        *bar = 42;
}

Works on ILP32 mode machines (both endiannesses), «works» on I32LP64 mode machines (little endian), fails miserably on I32LP64 mode machines (big endian) *as it should*.

I32LP64 подкол а вот в IL32LLP64 все бы было нормально ох уж этот long понадеешся что он не вырастет никогда если в венде а он возмет и вырастет на лине и получится бага как выше в примере описана понадеешся на лине что вырастет на 64 битках он возмет да и не выростет на вендах снова багу в карман

anonymous
()

Ничего не понял. Что не так вычисляется? На 32 битах все нормально должно быть. Но код конечно непереносимый. На 64 битах возможен косяк с первым printf'ом (но в частном случае для AMD64 ABI прокатит). Правильно надо так:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void) {
   uint32_t a;
   uint64_t b,c,d;
   a=1149952;
   printf("a=%"PRId32"\n",a);
   b=(a*4)/1024;
   c=(a*4096)>>20;
   d=(a*4096)/(1024*1024);
   printf("b=%"PRId64" c=%"PRId64" d=%"PRId64"\n",b,c,d);
   return 0;
}
Deleted
()

> разъясните,пожалуйста,как происходит вычисление

#include <stdio.h>
#include <stdint.h>

int main(void) {
   uint32_t a;
   uint64_t b,c,d;
   a=1149952;               // a: 0x00118C00
   printf("a=%ld\n",a);
   b=(a*4)/1024;            // a: 0x00463000, b: 0x000000000000118C
   c=(a*4096)>>20;          // a: 0x18C00000 (overflow!), c: 0x000000000000018C
   d=(a*4096)/(1024*1024);  // a: 0x18C00000 (overflow!), d: 0x000000000000018C
   printf("b=%lld c=%lld d=%lld\n",b,c,d);
   return 0;
}
arsi ★★★★★
()
Ответ на: комментарий от arsi

Точно! Это я выше ерунду написал.

Deleted
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.