Пишу очень быстрый алгоритм поэтому для приведения чисел к неправильной дроби в качестве общего знаменателя для огромного массива чисел не НОК а максимальная степень 10. Для этого нужно быстро найти количество цифр после запятой . Делаю так: разделяю long double на мантису и порядок, сдвигаю мантиссу влево если порядок больше 36383 на значение (порядок-36383+1) и получаю значение после запятой. Это значение типа unsigned __int64(мантиса 64 бит) и сравниваю с 0, если не равно то умножаю на 10 и повторяю вот код: | Код | struct TBitLongDouble { unsigned __int64 m; unsigned int q:15; unsigned int s:1; }; union TLongDoubleConv { long double d; TBitLongDouble b; };
//--------------------------------------------------------------------------- unsigned int PorZnam(long double d) { TLongDoubleConv c; c.d=d; unsigned __int64 ds=c.b.m,kr; int sm=c.b.q-16382; if(sm>0) { ds<<=(unsigned)sm; } while(ds>0) { r++; d*=10.0; c.d=d; ds=c.b.m; sm=c.b.q-16382; if(sm>0) { ds<<=(unsigned)sm; } } return r; }
|
Но в некоторых числах появляются странные единицы после умножения на 10 и число знаков после запятой огромно например число 45,561111. Привожу отладочный код: | Код | struct TBitLongDouble { unsigned __int64 m; unsigned int q:15; unsigned int s:1; }; union TLongDoubleConv { long double d; TBitLongDouble b; };
struct TBit64 { unsigned int b63:1; unsigned int b62:1; unsigned int b64:1; unsigned int b60:1; unsigned int b59:1; unsigned int b58:1; unsigned int b57:1; unsigned int b56:1; unsigned int b55:1; unsigned int b54:1; unsigned int b53:1; unsigned int b52:1; unsigned int b51:1; unsigned int b50:1; unsigned int b49:1; unsigned int b48:1; unsigned int b47:1; unsigned int b46:1; unsigned int b45:1; unsigned int b44:1; unsigned int b43:1; unsigned int b42:1; unsigned int b41:1; unsigned int b40:1; unsigned int b39:1; unsigned int b38:1; unsigned int b37:1; unsigned int b36:1; unsigned int b35:1; unsigned int b34:1; unsigned int b33:1; unsigned int b32:1; unsigned int b31:1; unsigned int b30:1; unsigned int b29:1; unsigned int b28:1; unsigned int b27:1; unsigned int b26:1; unsigned int b25:1; unsigned int b24:1; unsigned int b23:1; unsigned int b22:1; unsigned int b21:1; unsigned int b20:1; unsigned int b19:1; unsigned int b18:1; unsigned int b17:1; unsigned int b16:1; unsigned int b15:1; unsigned int b14:1; unsigned int b13:1; unsigned int b12:1; unsigned int b11:1; unsigned int b10:1; unsigned int b9:1; unsigned int b8:1; unsigned int b7:1; unsigned int b6:1; unsigned int b5:1; unsigned int b4:1; unsigned int b3:1; unsigned int b2:1; unsigned int b1:1; unsigned int b0:1; }; union TUint64Bit { unsigned __int64 i; TBit64 b; AnsiString GetBit64() { AnsiString s; s=s+(AnsiString)b.b63; s=s+(AnsiString)b.b62; s=s+(AnsiString)b.b64; s=s+(AnsiString)b.b60; s=s+(AnsiString)b.b59; s=s+(AnsiString)b.b58; s=s+(AnsiString)b.b57; s=s+(AnsiString)b.b56; s=s+(AnsiString)b.b55; s=s+(AnsiString)b.b54; s=s+(AnsiString)b.b53; s=s+(AnsiString)b.b52; s=s+(AnsiString)b.b51; s=s+(AnsiString)b.b50; s=s+(AnsiString)b.b49; s=s+(AnsiString)b.b48; s=s+(AnsiString)b.b47; s=s+(AnsiString)b.b46; s=s+(AnsiString)b.b45; s=s+(AnsiString)b.b44; s=s+(AnsiString)b.b43; s=s+(AnsiString)b.b42; s=s+(AnsiString)b.b41; s=s+(AnsiString)b.b40; s=s+(AnsiString)b.b39; s=s+(AnsiString)b.b38; s=s+(AnsiString)b.b37; s=s+(AnsiString)b.b36; s=s+(AnsiString)b.b35; s=s+(AnsiString)b.b34; s=s+(AnsiString)b.b33; s=s+(AnsiString)b.b32; s=s+(AnsiString)b.b31; s=s+(AnsiString)b.b30; s=s+(AnsiString)b.b29; s=s+(AnsiString)b.b28; s=s+(AnsiString)b.b27; s=s+(AnsiString)b.b26; s=s+(AnsiString)b.b25; s=s+(AnsiString)b.b24; s=s+(AnsiString)b.b23; s=s+(AnsiString)b.b22; s=s+(AnsiString)b.b21; s=s+(AnsiString)b.b20; s=s+(AnsiString)b.b19; s=s+(AnsiString)b.b18; s=s+(AnsiString)b.b17; s=s+(AnsiString)b.b16; s=s+(AnsiString)b.b15; s=s+(AnsiString)b.b14; s=s+(AnsiString)b.b13; s=s+(AnsiString)b.b12; s=s+(AnsiString)b.b11; s=s+(AnsiString)b.b10; s=s+(AnsiString)b.b9; s=s+(AnsiString)b.b8; s=s+(AnsiString)b.b7; s=s+(AnsiString)b.b6; s=s+(AnsiString)b.b5; s=s+(AnsiString)b.b4; s=s+(AnsiString)b.b3; s=s+(AnsiString)b.b2; s=s+(AnsiString)b.b1; s=s+(AnsiString)b.b0; AnsiString ss; for(int i=1;i<=s.Length();i++) { ss=s.SubString(i,1)+ss; } return ss; }; };
//--------------------------------------------------------------------------- unsigned int PorZnam(long double d) { TUint64Bit b64;//для отладки и все что с ней связано
TLongDoubleConv c; c.d=d; unsigned __int64 ds=c.b.m,kr; int sm=c.b.q-16382; b64.i=ds; Form1->ListBox1->Items->Add((AnsiString)sm+":"+b64.GetBit64()); unsigned int r=0; if(sm>0) { ds<<=(unsigned)sm; } /*if(sm<0) { ds>>=(unsigned)(-sm); }*/ while(ds>0) { r++; d*=10.0; c.d=d; ds=c.b.m; sm=c.b.q-16382; b64.i=ds; Form1->ListBox1->Items->Add((AnsiString)sm+":"+b64.GetBit64()); if(sm>0) { ds<<=(unsigned)sm; } /*if(sm<0) { ds>>=(unsigned)(-sm); }*/ } return r; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { ListBox1->Clear(); TLongDoubleConv c; c.d=Edit1->Text.ToDouble(); Edit2->Text=c.b.s; Edit3->Text=c.b.q; Edit4->Text=c.b.m; Edit5->Text=PorZnam(c.d); } //---------------------------------------------------------------------------
|
Тут нужно 5 эдитов и 1 листбокс. Попробуйте. Очень прошу помощи.
|