Technical Article

Inžinerinės funkcijos Delphi aplinkoje: pagrindų konvertavimas, kompleksiniai skaičiai

Inžinerinė funkcijų šeima Excel programoje atrodo kaip lengviausia funkcijų žinyno dalis. DEC2BIN paverčia skaičių dvejetaine eilute. HEX2DEC paverčia jį atgal. IMSUM sudeda du kompleksinius skaičius. Kiekviena iš jų atrodo kaip paprastas formatavimo pratimas. Taip nėra. Už šių pavadinimų slepiasi dešimties bitų papildomas kodas (angl. two's complement), kurio dauguma programuotojų nelietė nuo kompiuterių architektūros paskaitų, kompleksinių skaičių formatas, kuris gyvena tik eilutėse, ir bitiniai operatoriai, kurie tyliai perpildys 64 bitų sveikąjį skaičių, jei atliksite poslinkį prieš patikrindami. Skaičiuoklės variklis, kuris tiksliai atkuria Excel, negali nieko iš to suapvalinti

Funkcijos skirstomos į tris grupes, ir kiekviena grupė slepia skirtingus spąstus. Pagrindo konvertavimas yra susijęs su neigiamais skaičiais ir kiekvieno pagrindo slenksčiais. Kompleksinė aritmetika yra susijęs su eilutės analizavimu ir formatavimu. Bitinės operacijos yra susijusios su išlikimu Int64 ribose. Šiame straipsnyje apžvelgiama kiekviena grupė, kaip jas įgyvendina HotXLS, su darbalapio iškvietimais, kuriuos iš tikrųjų rašytumėte

Pagrindo konvertavimas ir dešimties bitų papildomas kodas

Tiesioginė kryptis yra ta dalis, kurios tikisi visi. DEC2BIN(9) pateikia "1001", o pasirinktinis antrasis argumentas papildo rezultatą nulių užpildymu iš kairės iki fiksuoto pločio. Spąstai yra neigiama įvestis. Excel nerašo minuso ženklo. Ji užkoduoja reikšmę kaip dešimties skaitmenų papildomo kodo eilutę tiksliniame pagrinde, todėl DEC2BIN(-5,10) grąžina "1111111011", o ne ką nors su ženklu. Vietos argumentas yra ignoruojamas, kai reikšmė yra neigiama, nes kodavimas jau yra prisegtas ties dešimčia skaitmenų

Dešimt skaitmenų yra fiksuotas biudžetas, ir šis biudžetas nustato vaizduojamą diapazoną vienam pagrindui. Dvejetainėje sistemoje dydis, kuris persiverčia į neigiamą pusę, yra 512, o ciklo modulis yra 1024, todėl dvejetainė eilutė yra su ženklu tik tada, kai ji yra tiksliai dešimties simbolių ilgio ir jos reikšmė yra bent 512. Ta pati idėja mastelizuojama su pagrindu. Aštuntainė sistema naudoja pusės slenkstį 2^29 ir pilną 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, o sukaupta reikšmė yra ties pusės slenksčiu arba virš jo, jis atima pilną modulį, kad atkurtų pasirašytą reikšmę. Devynių simbolių eilutė visada yra neigiama

Koduotuvas yra veidrodinis vaizdas. Neigiama reikšmė konvertuojama skaitmuo po skaitmens ir pasirinktinai papildoma nuliais iki pageidaujamo pločio, ir ji atmetama, jei perpildo pagrindo teigiamas lubas arba jei pageidaujamas plotis yra per siauras jai talpinti. Neigiama reikšmė pirmiausia perkeliama į diapazoną pridedant pilną modulį, kuris paverčia ją reikšme, kurios pagrindo atvaizdas visada yra dešimt skaitmenų, o tada skaitmenys išvedami su priekiniais nuliais pločiui užpildyti. Vienintelė bendra diapazono patikra – simetriškos apatinės ir viršutinės ribos vienam pagrindui – yra tai, kas išlaiko DEC2BIN, DEC2OCT ir DEC2HEX suderinamus vienas su kitu ties jų ribomis

Taip palieka kryžminius pagrindų konvertavimus, tokius kaip HEX2BIN ir OCT2HEX, kurie keičia pagrindą neperėję per dešimtainį pavadinimą funkcijoje. Įgyvendinimas neneša atskiros rutinos kiekvienai sutvarkytai porai. Jis analizuoja įvesties eilutę į pasirašytą dešimtainę reikšmę, naudodamas šaltinio pagrindą, o tada suformatuoja tą dešimtainę reikšmę į tikslinį pagrindą. Dešimtainė sistema yra ašis. Viena analizavimo rutina ir viena formatavimo rutina, sujungtos, apima kiekvieną derinį, ir kadangi abi pusės dalijasi ta pačia dešimties skaitmenų pasirašyta konvencija, neigiama reikšmė išgyvena kelionę su nepažeistu ženklu

Kompleksiniai skaičiai yra eilutės, todėl darbas yra analizavimas

Excel neturi kompleksinių duomenų tipo. Kompleksinė reikšmė yra eilutė "a+bi", ir kiekviena IM šeimos funkcija priima šias eilutes ir grąžina vieną atgal. COMPLEX sukuria eilutę iš realiosios ir tariamosios dalies. IMSUM, IMSUB, IMPRODUCT ir IMDIV analizuoja savo argumentus, atlieka aritmetiką su skaitinėmis dalimis ir suformatuoja rezultatą atgal į eilutę. Skaitinis darbas yra studentų algebra. Sunkumas yra visiškai turnigumas paversti tekstą į du slankiojo kablelio skaičius patikimai, ir būtent čia vidinis analizatorius užsidirba savo duoną

Dvi detalės tame analizatoriuje yra lengvai sugadinamos. Pirmoji yra plikas tariamasis vienetas. Eilutė "i" reiškia vieną kartą i, o ne nulį ir ne klaidą, todėl kai koeficientas prieš priesagą yra tuščias arba yra vienas pliuso ženklas, analizatorius turi jį perskaityti kaip reikšmę 1, o vieną minusą – kaip -1. Praleiskite tai, ir IMSUM("i","i") nustos būti 2i. Antroji yra mokslinė notacija, susidurianti su ženklu, kuris skiria realiąją ir tariamąją dalis. Analizatorius randa tą skirtuką ieškodamas pliuso arba minuso, tačiau skaičius, parašytas kaip "1.5E-3", turi minusą, kuris priklauso eksponentui. Todėl paieška atsisako traktuoti pliusą ar minusą kaip skirtuką, kai simbolis iškart prieš jį yra e arba E. Be šios apsaugos realioji dalis būtų perplėšta per pusę ties eksponento ženklu ir analizavimas nepavyktų ties visiškai teisinga įvestimi

Pati priesaga yra išsaugoma, o ne normalizuojama. Excel priima ir i, ir j, o HotXLS prisimena, kurią naudojo įvestis, kad suformatuotas rezultatas neštų tą pačią raidę. Formatavimas tada taiko įprastus sutrumpinimus: tariamoji dalis iš vieno spausdinama kaip tik priesaga, minus vienas kaip -i, nulinė tariamoji dalis subliūkšta į paprastą realiąją, o nulinė realioji dalis numeta 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ę į poliarinę formą, pritaiko operaciją moduliui ir argumentui ir konvertuoja atgal. Kvadratinė šaknis padalija argumentą pusiau ir paima modulio šaknį. Laipsnis padaugina argumentą ir pakelia modulį. Daryti tai bet kokiu kitu būdu reikštų iš naujo išvesti kiekvieną tapatybę stačiakampėje formoje, o tai yra ir daugiau kodo, ir mažiau skaitinio stabilumo šalia šakų pjūvių

Bitiniai operatoriai ir perpildymas, kurį turite patikrinti pirmiausia

Excel 2013 pridėjo BITAND, BITOR, BITXOR, BITLSHIFT ir BITRSHIFT. Operandai yra apriboti: kiekvienas turi būti neneigiamas sveikasis skaičius, ne didesnis nei 2^48 minus 1, o bet koks trupmeninis ar neigiamas argumentas yra skaitinė klaida. Šis dangtelis yra pakankamai dosnus, kad apimtų bet kurį tikrovišką vėliavėlių rinkinį, išlikdamas toli gražu tiksliai vaizduojamo double diapazono ribose, o tai svarbu, nes Excel kiekvieną skaitinį argumentą perduoda kaip slankiojo kablelio reikšmę

Poslinkio funkcijos neša vienintelę tvarkos taisyklę, kuri tikrai kanda. Kairysis poslinkis gali sukurti reikšmę, daug didesnę už jos įvestį, ir jei pirmiausia atliksite shl, o po to patikrinsite rezultatą, jau būsite perpildę Int64 ir testas bus beprasmis. Tikrinimas turi vykti prieš poslinkį. HotXLS palygina operandą su lubomis, pastumtomis į dešinę per poslinkio dydį, ir tik jei operandas telpa, jis atlieka tikrąjį kairįjį poslinkį. Poslinkio dydis virš 53 bitų yra atmetamas iškart, o neigiamas poslinkis tiesiog apverčia kryptį, todėl BITLSHIFT su neigiamu skaičiumi elgiasi kaip dešinysis poslinkis. Principas apibendrinamas toli už šios vienos funkcijos: kai apsauga egzistuoja perpildymui išvengti, ji turi veikti įvestyse, o ne rezultate, kurį 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 priesaga

Bitiniai operatoriai ir ilgas kitų po 2007 metų papildymų sąrašas sąveikauja su pavadinimų schema, kuri neturi nieko bendra su tuo, ką jie skaičiuoja, ir viskuo su tuo, kaip Excel juos saugo. Originalus dvejetainis darbalapio formatas priskyrė kiekvienai įmontuotai funkcijai skaitinį lizdą fiksuotoje lentelėje. Funkcijos, išrastos po to, kai ta lentelė buvo užšaldyta, neturi lizdo. Norint išsaugoti tokią funkciją faile ir kad šiuolaikinė Excel ją atpažintų, pavadinimas rašomas su _xlfn. priešdėliu, todėl BITAND diske saugomas kaip _xlfn.BITAND, net jei vartotojas įveda tik BITAND

Spąstai yra tai, kad taisyklė nėra vienoda. Kai kurioms naujesnėms funkcijoms buvo suteikti lentelės lizdai ir jos rašomos plikos, o kelios pasenusios paslėptos funkcijos taip pat rašomos be priešdėlio, nepaisant jų amžiaus. HotXLS saugo aiškų baltąjį sąrašą, kuriems pavadinimams reikia priešdėlio, prideda jį rašant ir nuima skaitant, todėl formulės tekstas, kurį nustatote ir perskaitote atgal, visada yra švarus, į Excel nukreiptas pavadinimas. Nustatote =BITLSHIFT(5,2), failas laiko _xlfn.BITLSHIFT, o reikšmė grįžta kaip 20 nepriklausomai nuo to. Priešdėlis yra saugojimo detalė, kuri niekada neturėtų nutekėti į formules, su kuriomis dirbate kode

Visko sujungimas darbalapyje

Viešasis API neprašo jūsų apie tai galvoti. Kuriate darbaknygę iš WideString langelių reikšmių ir iškviečiate norimą eksporto įėjimo tašką. Kodavimo sprendimai vyksta kiekvieno rašytuvo viduje. Žemiau pateiktas pavyzdys užsėja lapą tekstu keliomis rašto sistemomis, o tada rašo ir RTF failą, ir HTML failą iš tos pačios darbaknygės, kad abu keliai veiktų prieš identišką įvestį

Abu iškvietimai grąžina Integer būseną ir abu sunaudoja tą patį atmintyje esantį tekstą. Niekas kviečiančiame kode nedeklaruoja kodų lentelės ir neišsuka simbolio, nes atsakomybė tenka rašytuvui, kuris žino savo formatą. Darbaknygės lygio SaveAsCSV seka tą pačią formą, jei jums reikia eksporto su skirtukais iš identiško šaltinio

Unicode saugumas yra pagal kelią, o ne pagal biblioteką