Inžinerinių funkcijų šeima „Excel“ programoje atrodo kaip lengviausia funkcijų žinyno dalis. DEC2BIN paverčia skaičių dvejetaine eilute. HEX2DEC jį grąžina atgal. IMSUM sudeda du kompleksinius skaičius. Kiekvienas iš jų atrodo kaip formatavimo užduotis. Taip nėra. Už šių pavadinimų slypi dešimties bitų dviejų komplemento koduotė, su kuria dauguma kūrėjų nebuvo susidūrę nuo kompiuterių architektūros paskaitų, kompleksinių skaičių formatas, kuris egzistuoja vien tik eilutėse, ir bitinės operacijos, kurios nepastebimai perpildys 64 bitų sveikąjį skaičių, jei poslinkį atliksite prieš patikrindami. Skaičiuoklės variklis, tiksliai atkartojantis „Excel“, negali nieko iš to suapvalinti
Funkcijos padalytos į tris grupes, ir kiekviena grupė slepia skirtingus spąstus. Bazių konvertavimas yra susijęs su neigiamais skaičiais ir baziniais slenksčiais. Kompleksinė aritmetika skirta eilutės analizavimui ir formatavimui. Bitinės operacijos yra apie išlikimą Int64 ribose. Šiame straipsnyje apžvelgiama kiekviena grupė, kaip ją realizuoja „HotXLS“, kartu su skaičiuoklės iškvietimais, kuriuos iš tikrųjų rašytumėte
Bazių konvertavimas ir dešimties bitų dviejų komplementas
Tiesioginė kryptis yra ta dalis, kurios visi tikisi. DEC2BIN(9) duoda "1001", o pasirenkamas antrasis argumentas užpildo rezultatą nuliais iš kairės iki fiksuoto ilgio. Spąstai yra neigiama įvestis. „Excel“ nerašo minuso ženklo. Ji užkoduoja reikšmę kaip dešimties skaitmenų dviejų komplemento eilutę tikslinėje bazėje, todėl DEC2BIN(-5,10) grąžina "1111111011", o ne ką nors su ženklu. Argumentas „vietos“ ignoruojamas, kai reikšmė yra neigiama, nes koduotė jau yra fiksuota prie dešimties skaitmenų
Dešimt skaitmenų yra fiksuotas biudžetas, ir šis biudžetas nustato vaizduojamą diapazoną kiekvienoje bazėje. Dvejetainėje sistemoje dydis, kuris persijungia į neigiamą pusę, yra 512, o perpildymo modulis yra 1024, todėl dvejetainė eilutė turi ženklą tik tada, kai ji yra lygiai dešimties simbolių ilgio ir jos reikšmė yra bent 512. Ta pati idėja masteliuojama kartu su baze. Aštuntainė sistema naudoja pusės slenkstį, lygų 2^29, ir visą modulį 2^30. Šešioliktainė naudoja 2^39 ir 2^40. „HotXLS“ skaitytuvas taiko būtent šią taisyklę: jis kaupia skaitmenis ir tik tada, kai eilutė yra dešimties simbolių pločio ir sukaupta reikšmė yra lygi arba didesnė už pusės slenkstį, jis atima visą modulį, kad atkurtų reikšmę su ženklu. Devynių simbolių eilutė visada yra neneigiama, nesvarbu, kokio dydžio ji būtų
Koduotuvas yra veidrodinis atspindys. Neneigiama reikšmė konvertuojama po vieną skaitmenį ir, jei pageidaujama, užpildoma nuliais iki prašomo pločio, ir ji atmetama, jei viršija bazės teigiamą ribą arba jei prašomas plotis yra per mažas jai sutalpinti. Neigiama reikšmė pirmiausia įvedama į diapazoną pridedant visą modulį, kuris paverčia ją reikšme, kurios bazinis atvaizdavimas visada yra dešimt skaitmenų, o tada skaitmenys išvedami su priekiniais nuliais, kad užpildytų plotį. Vienintelis bendras diapazono patikrinimas, simetriškos apatinės ir viršutinės ribos kiekvienai bazei, yra tai, kas užtikrina, kad DEC2BIN, DEC2OCT ir DEC2HEX būtų nuoseklūs vienas kito atžvilgiu savo kraštuose
Lieka konvertavimai tarp bazių – tokie, kaip HEX2BIN ir OCT2HEX, kurie keičia bazę nepereidami per dešimtainę sistemos dalį funkcijos pavadinime. Realizacija neturi atskiros procedūros kiekvienai sutvarkytai porai. Ji išanalizuoja įvesties eilutę į dešimtainę reikšmę su ženklu naudodama šaltinio bazę, o po to tą dešimtainę reikšmę suformatuoja į paskirties bazę. Dešimtainė bazė yra ašis. Viena analizavimo procedūra ir viena formatavimo procedūra, jas sujungus, apima kiekvieną kombinaciją, ir kadangi abi pusės dalijasi ta pačia dešimties skaitmenų konvencija su ženklu, neigiama reikšmė išlaiko savo ženklą nepažeistą šios kelionės metu
Kompleksiniai skaičiai yra eilutės, todėl visas darbas yra analizavimas
„Excel“ neturi kompleksinių duomenų tipo. Kompleksinė reikšmė yra eilutė "a+bi", ir kiekviena funkcija IM šeimoje priima šias eilutes ir vieną grąžina atgal. COMPLEX sukuria eilutę iš realiosios ir menamosios dalies. IMSUM, IMSUB, IMPRODUCT ir IMDIV analizuoja savo argumentus, atlieka aritmetinius veiksmus su skaitinėmis dalimis ir rezultatą suformatuoja atgal į eilutę. Skaitmeninis darbas yra bakalauro lygio algebra. Sunkumas visiškai slypi tame, kaip patikimai paversti tekstą dviem slankiojo kablelio skaičiais, ir būtent čia vidinis analizatorius atlieka savo svarbiausią darbą
Šiame analizatoriuje lengva suklysti dėl dviejų detalių. Pirmoji yra plikas menamasis vienetas. Eilutė "i" reiškia vienas padaugintas iš i, ne nulis ir ne klaida, todėl, kai koeficientas prieš priesagą yra tuščias arba yra tik pliuso ženklas, analizatorius turi nuskaityti tai kaip reikšmę 1, o pliką minusą – kaip -1. Praleiskite tai, ir IMSUM("i","i") nustos buvęs 2i. Antroji klaida – mokslinis žymėjimas, susiduriantis su ženklu, kuris atskiria realiąją ir menamąją dalis. Analizatorius suranda tą skyriklį ieškodamas pliuso ar minuso, tačiau skaičius, užrašytas kaip "1.5E-3", turi minusą, priklausantį eksponentei. Todėl nuskaitymas atsisako traktuoti pliusą ar minusą kaip skyriklį, kai simbolis prieš pat jį yra e arba E. Be šios apsaugos realioji dalis būtų perplėšta per pusę ties eksponentės ženklu, ir analizė nepavyktų naudojant visiškai galiojančią įvestį
Pati priesaga yra išsaugoma, o ne normalizuojama. „Excel“ priima tiek i, tiek j, o „HotXLS“ prisimena, kurį iš jų naudojo įvestis, todėl suformatuotas rezultatas turi tą pačią raidę. Formatuojant taikomos įprastos trumpinimo taisyklės: menamoji vieneto dalis spausdinama tik kaip priesaga, minus vienas kaip -i, nulinė menamoji dalis sutraukiama į paprastą realųjį skaičių, o nulinė realioji dalis atmeta priekinį 0+
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
begin
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Engineering');
// Negative input: a ten-bit two's complement, places argument ignored.
Sheet.Cells[1, 1].Value := Sheet.Calculate('=DEC2BIN(-5,10)'); // 1111111011
// Complex multiply on two "a+bi" strings.
Sheet.Cells[2, 1].Value := Sheet.Calculate('=IMPRODUCT("3+4i","1+2i")'); // -5+10i
finally
Book.Free;
end;
end;
Transcendentinės kompleksinės funkcijos, tarp jų IMSQRT, IMEXP, IMLN ir IMPOWER, neveikia stačiakampėse koordinatėse. Jos konvertuoja išanalizuotą reikšmę į polinę formą, pritaiko operaciją moduliui bei argumentui ir konvertuoja atgal. Kvadratinė šaknis perpjauna argumentą per pusę ir paima modulio šaknį. Kėlimas laipsniu padaugina argumentą ir pakelia modulį. Darant tai bet kokiu kitu būdu reikėtų iš naujo išvesti kiekvieną tapatybę stačiakampėje formoje, o tai reiškia daugiau kodo ir mažesnį skaitmeninį stabilumą šalia šakų pjūvių
Bitinės operacijos ir perpildymas, kurį privalote patikrinti pirmiausia
„Excel 2013“ pridėjo BITAND, BITOR, BITXOR, BITLSHIFT ir BITRSHIFT. Operandai yra ribojami: kiekvienas turi būti neneigiamas sveikasis skaičius, ne didesnis kaip 2^48 minus 1, o bet koks trupmeninis ar neigiamas argumentas yra skaitinė klaida. Ši riba yra pakankamai dosni, kad apimtų bet kokį realistišką vėliavėlių rinkinį, kartu išliekant tiksliai atvaizduojamame double tipo diapazone. Tai svarbu, nes „Excel“ kiekvieną skaitmeninį argumentą perduoda kaip slankiojo kablelio reikšmę
Poslinkio funkcijos turi vieną eiliškumo taisyklę, kuri iš tikrųjų kelia problemų. Poslinkis į kairę gali sukurti reikšmę, daug didesnę nei jos įvestis, ir jei pirmiausia atliksite shl, o po to patikrinsite rezultatą, jau būsite perpildę Int64, ir testas neteks prasmės. Patikrinimas turi būti atliktas prieš poslinkį. „HotXLS“ lygina operandą su viršutine riba, paslinkta į dešinę per poslinkio dydį, ir tik tuo atveju, jei operandas telpa, jis atlieka tikrąjį poslinkį į kairę. Poslinkio dydis, viršijantis 53 bitus, atmetamas iš karto, o neigiamas poslinkis tiesiog pakeičia kryptį, todėl BITLSHIFT su neigiamu skaičiumi elgiasi kaip poslinkis į dešinę. Šis principas apibendrinamas gerokai toliau nei tik ši viena funkcija: kai egzistuoja apsauga nuo perpildymo, ji turi būti taikoma įvestims, niekada ne rezultatui, kurį ji turėjo apsaugoti
// Bitwise calls evaluate the same way through Calculate.
Sheet.Cells[3, 1].Value := Sheet.Calculate('=BITAND(13,11)'); // 9
Sheet.Cells[4, 1].Value := Sheet.Calculate('=BITLSHIFT(5,2)'); // 20
Sheet.Cells[5, 1].Value := Sheet.Calculate('=BITRSHIFT(40,3)'); // 5
Ateities funkcijos ir _xlfn pavadinimo priešdėlis
Bitinės operacijos ir ilgas kitų po 2007 m. atsiradusių papildymų sąrašas sąveikauja su pavadinimų schema, kuri neturi nieko bendro su tuo, ką jie apskaičiuoja, bet yra visiškai susijusi su tuo, kaip „Excel“ juos saugo. Originalus dvejetainis skaičiuoklės formatas kiekvienai integruotai funkcijai skyrė skaitmeninį lizdą fiksuotoje lentelėje. Funkcijos, išrastos po to, kai ta lentelė buvo užfiksuota, neturi lizdo. Norint išsaugoti tokią funkciją faile ir kad šiuolaikinė „Excel“ ją atpažintų, pavadinimas rašomas su priešdėliu _xlfn., todėl BITAND diske saugomas kaip _xlfn.BITAND, nors vartotojas visada įveda tik BITAND
Kabliukas tas, kad ši taisyklė nėra vienoda. Kai kurioms naujesnėms funkcijoms buvo suteikti lentelės lizdai, ir jos rašomos be priešdėlio, tuo tarpu kelios senos paslėptos funkcijos taip pat rašomos be priešdėlio, nepaisant jų amžiaus. „HotXLS“ išlaiko aiškų „baltąjį sąrašą“, kokiems pavadinimams reikia priešdėlio, prideda jį rašant ir pašalina skaitant, todėl formulės tekstas, kurį nustatote ir perskaitote, visada yra švarus, į „Excel“ orientuotas pavadinimas. Jūs nustatote =BITLSHIFT(5,2), faile saugoma _xlfn.BITLSHIFT, o reikšmė grįžta kaip 20, nepaisant to. Priešdėlis yra saugojimo detalė, kuri niekada neturėtų prasiskverbti į formules, su kuriomis dirbate kode
Visko sujungimas skaičiuoklėje
Viso to viešasis paviršius yra nedidelis. Sukurkite TXLSXWorkbook, pridėkite lapą ir arba įrašykite formulę į langelį per Cells[Row, Col].Formula bei perskaičiuokite, arba apskaičiuokite išraišką tiesiogiai naudodami skaičiuoklės lapo Calculate metodą, kuris sukompiliuoja formulę tam lapui ir grąžina Variant. Aukščiau pateiktuose pavyzdžiuose naudojamas Calculate, nes tai rodo vieno inžinerinio iškvietimo rezultatą be supančios lapo būsenos, tačiau tos pačios funkcijos apskaičiuojamos identiškai tikrų langelių formulėse, kai darbo knyga yra perskaičiuojama
Reikėtų nepamiršti koduočių, o ne iškvietimo vietų. Dvejetainė eilutė turi ženklą tik ties dešimt skaitmenų ir tik peržengus pusės slenkstį jos bazei. Kompleksinis skaičius yra tekstas, tuščias menamasis koeficientas yra vienas, o analizatorius peržengia eksponentės e. Poslinkis į kairę patikrinamas prieš jį atliekant. Teisingai supraskite šiuos keturis faktus, ir inžinerijos šeima nustos buvusi „netikėtumų dėl vieno ženklo“ šaltiniu
Jei tą patį variklį prijungiate prie savo srities matematikos, apdorotojo registravimo ir reikšmių grąžinimo mechanika aprašyta mūsų straipsnyje apie formulės variklio išplėtimą tinkintomis funkcijomis, o kai tos formulės turi pasiekti kitus lapus pagal pavadinimą, o ne pagal langelio adresą, apžvalgoje apie apibrėžtus pavadinimus ir kryžminio lapo formules parodoma, kaip išsprendžiamos nuorodos. Čia aprašytos inžinerinės funkcijos tiekiamos kaip HotXLS skaičiuoklių komponento, skirto „Delphi“ ir „C++Builder“, dalis, kartu su skaitymo, rašymo ir skaičiavimo API, kurie aptariami kituose šio tinklaraščio straipsniuose