long double x = 1.3624742724742527487782123333;
// У меня в win32 в консоли 1.3624742724742526789, т.е. 15 знаков совпадают, остальные уже нет
std::cout.precision( 20 );
std::cout << x << '\n';
Большие числа
Такой вопрос. Необходимо в проге точно получать большие числа. Чтобу программа писала не 2Е23, а точное число. У всех типов инт происходит переполнение, а лонг дабл выдаёт число с мантиссой - последние разряды в числе тогда теряются. Никто не знает как это отключить?
вроде бы машина физически это не осилит.....
Цитата:
Originally posted by gray_k
Такой вопрос. Необходимо в проге точно получать большие числа. Чтобу программа писала не 2Е23, а точное число. У всех типов инт происходит переполнение, а лонг дабл выдаёт число с мантиссой - последние разряды в числе тогда теряются. Никто не знает как это отключить?
Такой вопрос. Необходимо в проге точно получать большие числа. Чтобу программа писала не 2Е23, а точное число. У всех типов инт происходит переполнение, а лонг дабл выдаёт число с мантиссой - последние разряды в числе тогда теряются. Никто не знает как это отключить?
Попробуй использовать тип double. Покрайней мере мне это помогло при работе с большими числами.
Цитата:
Originally posted by bercut
Попробуй использовать тип double. Покрайней мере мне это помогло при работе с большими числами.
Попробуй использовать тип double. Покрайней мере мне это помогло при работе с большими числами.
Что ты понимаешь под большими числами ?
Например double x=100000000
выдаст: 1е+07
а это еще не совсем астрономическая цифра......
для работы с очень большими числами я однажды видел специальный класс. идея в том, что числа хранятся как символьные строки, а все операциии с ними выполняются по частям... то есть берется несколько младших разрядов, конвертируются в число, над которым производятся какие-то действия, потом несколько более старших разрядов и т.д. результат - опять строка, составленная из фрагментов частичных операций...
Цитата:
Originally posted by Pennywise
Что ты понимаешь под большими числами ?
Например double x=100000000
выдаст: 1е+07
а это еще не совсем астрономическая цифра......
Что ты понимаешь под большими числами ?
Например double x=100000000
выдаст: 1е+07
а это еще не совсем астрономическая цифра......
Я оперировал с миллиардами и все у меня выдавалось как надо.
Уж и не знаю что тебе и сказать.
Цитата:
Originally posted by bercut
Я оперировал с миллиардами и все у меня выдавалось как надо.
Уж и не знаю что тебе и сказать.
Я оперировал с миллиардами и все у меня выдавалось как надо.
Уж и не знаю что тебе и сказать.
Лады...может ты и прав.....наверно зависит от компилятора....
я проверял в Borland C++ 5.2 и VC 6.0.........
Цитата:
Originally posted by bercut
Я оперировал с миллиардами и все у меня выдавалось как надо.
Уж и не знаю что тебе и сказать.
Я оперировал с миллиардами и все у меня выдавалось как надо.
Уж и не знаю что тебе и сказать.
Милиарды мало. речь идёт о 16 и более порядках:)
Цитата:
Originally posted by gray_k
Милиарды мало. речь идёт о 16 и более порядках:)
Милиарды мало. речь идёт о 16 и более порядках:)
А это уже не важно, т.к. на миллиардах уже происходит конвертирование в спец. формат.
Ссылка:HugeInt
Дело можно исправить функцией std::cout.precision( streamsize ):
std::cout.precision( 20 ); // 20 знаков после запятой
Код:
Если поекспериментировать, то можно заметить, что после определенного числа знаков, наблюдается естественная закономерность. Догадайтесь какая :).
Насчет HugeInt могу предложить вот это:
Код:
struct u128
{
public:
u128( int v ) : a(v), b(0UL), c(0UL), d(0UL) {};
u128( u32 v ) : a(v), b(0UL), c(0UL), d(0UL) {};
//u128( const u128 &x ) : a(x.a), b(x.b), c(x.c), d(x.d) {};
public:
u32 a, b, c, d;
};
#pragma pack( pop )
void inc( u128 *x )
{
__asm__
(
"addl $1, (%%eax) ;"
"adcl $0, 4(%%eax) ;"
"adcl $0, 8(%%eax) ;"
"adcl $0, 12(%%eax) ;"
:
: "a" (x)
);
};
void dec( u128 *x )
{
__asm__
(
"subl $1, (%%eax) ;"
"sbbl $0, 4(%%eax) ;"
"sbbl $0, 8(%%eax) ;"
"sbbl $0, 12(%%eax) ;"
:
: "a" (x)
);
};
void add( u128 *x, const u128 *y )
{
__asm__
(
"movl (%%ebx), %%edx ;"
"addl %%edx, (%%eax) ;"
"movl 4(%%ebx), %%edx ;"
"adcl %%edx, 4(%%eax) ;"
"movl 8(%%ebx), %%edx ;"
"adcl %%edx, 8(%%eax) ;"
"movl 12(%%ebx), %%edx ;"
"adcl %%edx, 12(%%eax) ;"
:
: "a" (x), "b" (y)
);
};
void sub( u128 *x, const u128 *y )
{
__asm__
(
"movl (%%ebx), %%edx ;"
"subl %%edx, (%%eax) ;"
"movl 4(%%ebx), %%edx ;"
"sbbl %%edx, 4(%%eax) ;"
"movl 8(%%ebx), %%edx ;"
"sbbl %%edx, 8(%%eax) ;"
"movl 12(%%ebx), %%edx ;"
"sbbl %%edx, 12(%%eax) ;"
:
: "a" (x), "b" (y)
);
};
{
public:
u128( int v ) : a(v), b(0UL), c(0UL), d(0UL) {};
u128( u32 v ) : a(v), b(0UL), c(0UL), d(0UL) {};
//u128( const u128 &x ) : a(x.a), b(x.b), c(x.c), d(x.d) {};
public:
u32 a, b, c, d;
};
#pragma pack( pop )
void inc( u128 *x )
{
__asm__
(
"addl $1, (%%eax) ;"
"adcl $0, 4(%%eax) ;"
"adcl $0, 8(%%eax) ;"
"adcl $0, 12(%%eax) ;"
:
: "a" (x)
);
};
void dec( u128 *x )
{
__asm__
(
"subl $1, (%%eax) ;"
"sbbl $0, 4(%%eax) ;"
"sbbl $0, 8(%%eax) ;"
"sbbl $0, 12(%%eax) ;"
:
: "a" (x)
);
};
void add( u128 *x, const u128 *y )
{
__asm__
(
"movl (%%ebx), %%edx ;"
"addl %%edx, (%%eax) ;"
"movl 4(%%ebx), %%edx ;"
"adcl %%edx, 4(%%eax) ;"
"movl 8(%%ebx), %%edx ;"
"adcl %%edx, 8(%%eax) ;"
"movl 12(%%ebx), %%edx ;"
"adcl %%edx, 12(%%eax) ;"
:
: "a" (x), "b" (y)
);
};
void sub( u128 *x, const u128 *y )
{
__asm__
(
"movl (%%ebx), %%edx ;"
"subl %%edx, (%%eax) ;"
"movl 4(%%ebx), %%edx ;"
"sbbl %%edx, 4(%%eax) ;"
"movl 8(%%ebx), %%edx ;"
"sbbl %%edx, 8(%%eax) ;"
"movl 12(%%ebx), %%edx ;"
"sbbl %%edx, 12(%%eax) ;"
:
: "a" (x), "b" (y)
);
};
// В принципе можно реализовать и i256/u256, но вот только я не знаю, как реализовать на асме умножение с переносом без танца с бубном.
То же самое есть у SIMD. Можно найти во всяких xmmintrin.h, smmintrin.h. То что аппаратно, то быстрее, но есть не на всех камнях.