Comments 23
Есть классная книжка "Алгоритмические трюки для программистов" — в ней ещё много полезных приёмов по целочисленному умножению и делению.
+10
Есть у меня эта книга, только не всю прочитал. Там есть конкретно такой пример? Я не претендую на право первооткрывателя, но приведенный код придуман самостоятельно, хотя он и не сложный, а предварительное гугление результатов не дало
0
результат умножения имеет ту же разрядность, что и множители.
Да ну? Какого типа тогда будет результат умножения
unsigned char
на unsigned char
? +2
Все арифметические типы Уже int перед арифметикой приводятся к типу int. Т.е. unsigned char * unsigned char = int.
+1
Согласен. Нужно было написать что-то вроде:
«результат умножения целых типа не короче int имеет ту же разрядность, что и множители»
«результат умножения целых типа не короче int имеет ту же разрядность, что и множители»
0
Еще точнее: «C++ не умеет умножать целые короче int, а для целых не короче int разрядность результата совпадает с разрядностью умножения». Для long тоже можно изобрести что-то вроде:
Но это уже выходит за рамки условий поста. Там задача — остаться в рамках исходной разрядности.
long a, b;
//...
long long c = a*static_cast<long long>(b);
Но это уже выходит за рамки условий поста. Там задача — остаться в рамках исходной разрядности.
0
> В C/C++, в отличие от большинства ассемблеров,
> результат умножения имеет ту же разрядность, что и множители.
unsigned short a = 60000;
unsigned short b = 60000;
unsigned int i = a*b;
А так?
> результат умножения имеет ту же разрядность, что и множители.
unsigned short a = 60000;
unsigned short b = 60000;
unsigned int i = a*b;
А так?
+1
Модельный пример несколько высосан из пальца, ибо гораздо лучшим решением будет использование функции QueryPerformanceCounter.
-7
UFO just landed and posted this here
LARGE_INTEGER c;
QueryPerformanceCounter(&c);
return c.QuadPart;
а в чем должна была быть проблема? этот фрагмент, конечно, забывает про секунды, но если тип результата позволит их вернуть, то можно просто прибавить их, умножив на 1000000000. разница в том, что здесь нет деления и оно не нужно вообще.
0
… особенно, где-нить на embedded системе вообще без ОС :)
+1
Нет, моедльный пример — в реально работающем проекте. Вот только операционка там — ядро линукс, а все драйвера — свои. Из сторонних библиотек только libc
+1
Не проще ли один раз посчитать TICKS_PER_NSEC?
-1
И чему оно будет равно? Обратите внимание, что в соответствии с условием вещественные типы использовать нельзя
+1
unsigned long long getNsec(unsigned long long ticks) {
static const unsigned long long _GCD_TPS_NSPS = gcd(NSEC_PER_SECOND, TICKS_PER_SECOND);
return ticks * (NSEC_PER_SECOND / _GCD_TPS_NSPS) / (TICKS_PER_SECOND / _GCD_TPS_NSPS);
};
0
Я для упрощения округлил до 1999000000ULL, полагая, что значение роли не играет. Считайте gcd = 1, такое будет, например, для TICKS_PER_SECOND = 1999000001ULL;
0
Сделал соответствующее исправление в тексте, чтобы не возникало дальнейших вопросов с GCD. Стоит также заметить, что в исходной задаче константы были взаимно просты, и лишь при подготовке начального варианта поста я произвел округление, которое по моему недогляду привело к еще одному решению через GCD.
0
Все корректно. Кое где можно было бы привести умножение вместо второй операции '%' — может съэкономить пару тактов, если часто вызываема будет, поскольку операция деления и взятия остатка не сможет быть даже гипотетически объединена в одну операцию конвеером процессора (существуют в разрыв им другие операции). Нахождение общего делителя интересный момент, но гораздо хуже, если коэффициенты будут иметь единицу в качестве онного.
0
Sign up to leave a comment.
Переполнение при умножении