Műszaki cikk

Delphi mérnöki függvények: Alapkonverzió, komplex matematika

A mérnöki család az Excelben úgy olvasható, mint a függvényreferencia legegyszerűbb sarka. A DEC2BIN egy számot bináris karakterlánccá alakít. A HEX2DEC visszaalakítja. Az IMSUM két komplex számot ad össze. Mindegyik egy formázási gyakorlatnak tűnik. De nem azok. Ezek a nevek mögött egy tízbites kettes kiegészítő kódolás rejtőzik, amelyet a legtöbb fejlesztő a számítógép-architektúra órák óta nem érintett, egy komplex számformátum, amely teljes egészében karakterláncokban él, és bitenkénti operátorok, amelyek csendben túlcsordulnak egy 64 bites egész számon, ha eltolás előtt nem ellenőrzöd. Egy táblázatkezelő motor, amely pontosan reprodukálja az Excelt, semmit sem tud kikerekíteni ezekből

A függvények három csoportra oszthatók, és mindegyik csoport más csapdát rejt. Az alapkonverzió a negatív számokról és az alaponkénti küszöbértékekről szól. A komplex aritmetika egy karakterlánc elemzéséről és formázásáról szól. A bitenkénti műveletek arról szólnak, hogy az Int64 határain belül maradjunk. Ez a cikk végigjárja az egyes csoportokat, ahogyan a HotXLS megvalósítja őket, azokkal a munkalaphívásokkal, amelyeket Ön ténylegesen megírna

Alapkonverzió és a tízbites kettes kiegészítő

Az előre mutató irány az a rész, amire mindenki számít. A DEC2BIN(9) a "1001" értéket adja, egy opcionális második argumentum pedig fix szélességre párnázza az eredményt balról. A csapda a negatív bemenet. Az Excel nem ír mínuszjelet. Az értéket tízjegyű kettes kiegészítő karakterláncként kódolja a célalapban, amiért a DEC2BIN(-5,10) a "1111111011" értéket adja vissza, nem pedig olyat, amiben van előjel. A helyek argumentum figyelmen kívül lesz hagyva, amint az érték negatív lesz, mert a kódolás már tíz számjegyre van rögzítve

A tíz számjegy egy rögzített költségvetés, és ez a költségvetés határozza meg a reprezentálható tartományt alaponként. A bináris rendszerben a nagyságrend, amely a negatív felébe fordul, 512, és a csomagolási modulus 1024, tehát egy bináris karakterlánc csak akkor előjeles, ha pontosan tíz karakter hosszú, és az értéke legalább 512. Ugyanez a gondolat skálázódik az alappal. Az oktális 2^29 fele küszöbértéket és 2^30 teljes modulust használ. A hexadecimális 2^39-et és 2^40-et használ. A HotXLS olvasó pontosan ezt a szabályt alkalmazza: felhalmozza a számjegyeket, és csak akkor, amikor a karakterlánc tíz karakter széles, és a felhalmozott érték a fele küszöbértéken vagy afelett van, akkor vonja ki a teljes modulust az előjeles érték helyreállításához. Egy kilenc karakteres karakterlánc mindig nem negatív, bármilyen nagy is legyen

A kódoló a tükörkép. Egy nem negatív értéket számjegyről számjegyre konvertál, és opcionálisan nullákkal egészít ki a kért szélességig, majd elutasítja, ha túlcsordul az alap pozitív plafonján, vagy ha a kért szélesség túl keskeny ahhoz, hogy elférjen. Egy negatív értéket először úgy hoz tartományba, hogy hozzáadja a teljes modulust, amely így egy olyan értékké válik, amelynek az alapi reprezentációja mindig tíz számjegyű, majd a számjegyeket vezető nullákkal bocsátja ki, hogy kitöltsék a szélességet. Az egyetlen megosztott tartományellenőrzés, a szimmetrikus alsó és felső határok alaponként, tartja következetesnek a DEC2BIN, DEC2OCT és DEC2HEX függvényeket egymással a peremeiknél

Ez hagyja meg a bázisok közötti konverziókat, olyanokat, mint a HEX2BIN és OCT2HEX, amelyek anélkül változtatnak alapot, hogy átmennének a decimálison a függvény nevében. A megvalósítás nem tartalmaz külön rutint minden rendezett párhoz. A bemeneti karakterláncot a forrásalap használatával elemzi egy előjeles decimális értékké, majd ezt a decimális értéket formázza a célalappá. A decimális a forgáspont. Egy elemző rutin és egy formázó rutin összesítve minden kombinációt lefed, és mivel mindkét fél osztozik ugyanazon a tízjegyű előjeles konvención, egy negatív érték túléli az utat úgy, hogy az előjele érintetlen marad

A komplex számok karakterláncok, így a munka az elemzés

Az Excel nem rendelkezik komplex adattípussal. A komplex érték egy "a+bi" karakterlánc, és az IM család minden függvénye beveszi ezeket a karakterláncokat, és visszaad egyet. A COMPLEX felépíti a karakterláncot egy valós és egy képzetes részből. Az IMSUM, az IMSUB, az IMPRODUCT és az IMDIV elemzi az argumentumokat, elvégzi az aritmetikát a numerikus részeken, majd az eredményt visszaformázza egy karakterlánccá. A numerikus munka egyetemi szintű algebra. A nehézség kizárólag a szöveg megbízhatóan két lebegőpontos számmá alakításában rejlik, és ez az a pont, ahol a belső elemző megkeresi a kenyerét

Ebben az elemzőben két apróságot könnyű elrontani. Az első a csupasz képzetes egység. Az "i" karakterlánc jelentése egy szer i, nem nulla és nem is hiba, ezért ha a szuffixum előtti együttható üres vagy csak egy pluszjel, az elemzőnek ezt 1-es értéknek kell olvasnia, az önálló mínuszjelet pedig -1-nek. Hagyd ki ezt, és az IMSUM("i","i") már nem lesz 2i. A második a tudományos jelölés, amely ütközik azzal az előjellel, amely elválasztja a valós és a képzetes részt. Az elemző úgy találja meg az elválasztót, hogy keres egy pluszt vagy mínuszt, de egy szám, amely "1.5E-3" formátumban van felírva, tartalmaz egy mínuszt, amely a kitevőhöz tartozik. A keresés ezért nem hajlandó a pluszt vagy mínuszt elválasztóként kezelni, ha az azt közvetlenül megelőző karakter az e vagy az E. Ezen védelem nélkül a valós rész félbeszakadna a kitevő előjelénél, és az elemzés elbukna egy tökéletesen érvényes bemeneten

Maga a szuffixum megmarad, ahelyett, hogy normalizálnánk. Az Excel az i és a j karaktereket is elfogadja, és a HotXLS megjegyzi, melyiket használta a bemenet, hogy a formázott eredmény ugyanazt a betűt hordozza. A formázás ezután a hagyományos rövidítéseket alkalmazza: az egy képzetes rész csak szuffixumként íródik ki, a mínusz egy mint -i, a nulla képzetes rész összeomlik egy sima valóssá, a nulla valós rész pedig eldobja a vezető 0+-t

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;

A transzcendens komplex függvények, köztük az IMSQRT, az IMEXP, az IMLN és az IMPOWER, nem derékszögű koordinátákban működnek. Átalakítják az elemzett értéket poláris formára, alkalmazzák a műveletet a moduluson és az argumentumon, majd visszaalakítják. A négyzetgyök megfelezi az argumentumot és gyököt von a modulusból. A hatvány megszorozza az argumentumot és megemeli a modulust. Bármilyen más módon történő elvégzésük azt jelentené, hogy újra le kellene vezetni minden azonosságot derékszögű formában, ami több kód és numerikusan kevésbé stabil a fiókágak közelében

A bitenkénti operátorok és a túlcsordulás, amelyet először kell ellenőrizni

Az Excel 2013 hozzáadta a BITAND, a BITOR, a BITXOR, a BITLSHIFT és a BITRSHIFT függvényeket. Az operandusok korlátozottak: mindegyiknek nem negatív egész számnak kell lennie, amely nem nagyobb, mint 2^48 mínusz 1, és bármely tört vagy negatív argumentum numerikus hibát okoz. Ez a felső határ elég nagylelkű ahhoz, hogy lefedjen bármilyen reális zászlókészletet, miközben bőven a dupla pontosságú számok pontosan ábrázolható tartományán belül marad, ami azért fontos, mert az Excel minden numerikus argumentumot lebegőpontos értékként ad át

Az eltolási függvények hordozzák az egyetlen olyan rendezési szabályt, amely valóban harap. Egy balra tolás a bemeneténél sokkal nagyobb értéket tud előállítani, és ha először végrehajtod az shl-t, és utána vizsgálod meg az eredményt, már túlcsordultál az Int64-en, és a teszt értelmetlen. Az ellenőrzésnek az eltolás előtt kell megtörténnie. A HotXLS összehasonlítja az operandust a plafonnal, amelyet jobbra tol az eltolás mértékével, és csak akkor hajtja végre a tényleges balra tolást, ha az operandus belefér. Az 53 bitnél nagyobb eltolási mértéket egyenesen elutasítja, a negatív eltolás pedig egyszerűen megfordítja az irányt, így a BITLSHIFT negatív számmal jobbra tolásként viselkedik. Az alapelv messze túlmutat ezen az egyetlen függvényen: ha van egy védelem a túlcsordulás megelőzésére, annak a bemeneteken kell futnia, soha nem azon az eredményen, amelyet meg akart védeni

// 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

A jövőbeli funkciók és az _xlfn név előtag

A bitenkénti operátorok és sok más, a 2007 utáni kiegészítés kölcsönhatásban áll egy olyan elnevezési sémával, amelynek semmi köze ahhoz, hogy mit számítanak ki, de mindent elmond arról, hogyan tárolja azokat az Excel. Az eredeti bináris munkalapformátum minden beépített függvényhez kijelölt egy numerikus helyet egy fix táblában. A tábla befagyasztása után feltalált funkcióknak nincs helyük. Ahhoz, hogy egy ilyen függvényt egy fájlba mentsünk, és a modern Excel felismerje, a nevet az _xlfn. előtaggal írják, tehát a BITAND fájlba mentve _xlfn.BITAND-ként jelenik meg, bár a felhasználó mindig csak BITAND-ot ír be

A bökkenő az, hogy a szabály nem egységes. Néhány újabb függvény kapott helyet a táblában, és tisztán van írva, míg néhány régi rejtett függvény szintén előtag nélkül íródik a kora ellenére. A HotXLS kifejezett engedélyezőlistát vezet arról, hogy mely neveknek van szükségük az előtagra, íráskor hozzáadja, olvasáskor pedig eltávolítja, így az a képletszöveg, amelyet beállít és visszaolvas, mindig a tiszta Excel-barát név. Beállítja az =BITLSHIFT(5,2)-t, a fájl tartalmazza az _xlfn.BITLSHIFT-et, de az érték visszajön mint 20, függetlenül mindentől. Az előtag egy tárolási részlet, amelynek soha nem szabadna kiszivárognia azokba a képletekbe, amelyekkel a kódban dolgozik

Mindezt összerakni egy munkalapon

Mindezek publikus felülete kicsi. Hozzon létre egy TXLSXWorkbook-ot, adjon hozzá egy munkalapot, és vagy írjon be egy képletet egy cellába a Cells[Row, Col].Formula-n keresztül és számolja újra, vagy értékeljen ki egy kifejezést közvetlenül a munkalap Calculate metódusával, amely az adott munkalappal szemben fordítja le a képletet, és egy Variant-ot ad vissza. A fenti példák a Calculate-ot használják, mert ez egyetlen mérnöki hívás eredményét mutatja meg a környező munkalap állapota nélkül, de ugyanezek a függvények azonosan kerülnek kiértékelésre a valódi cellaképletekben is, amikor a munkafüzet újraszámolódik

A kódolások a lényegesek, amelyeket érdemes észben tartani, nem a hívási helyek. Egy bináris karakterlánc csak tíz számjegynél, és csak az alapjához tartozó fele küszöbérték túllépése esetén előjeles. A komplex szám szöveg, egy üres képzetes együttható jelentése egy, az elemző pedig átlépi a kitevő e betűjét. A balra tolást ellenőrzik, mielőtt megtörténne az eltolás. Tartsa be ezt a négy tényt, és a mérnöki család többé nem lesz az előjelhibákból adódó meglepetések forrása

Ha saját tartományának matematikáját ugyanabba a motorba köti, a kezelő regisztrálásának és az értékek visszaadásának mechanikáját a képletmotor egyéni függvényekkel való kiterjesztéséről szóló cikkünk tárgyalja, és amikor ezeknek a képleteknek inkább név, mintsem cellacím alapján kell áthidalniuk a munkalapokat, a definiált nevekről és munkalapokon átívelő képletekről szóló útmutató megmutatja, hogyan oldódnak fel a hivatkozások. Az itt leírt mérnöki függvények a Delphi és a C++Builder számára készült HotXLS Spreadsheet Component részeként kerülnek szállításra, az ezen a blogon máshol bemutatott olvasási, írási és számítási API-k mellett