Teknik Makale

Delphi Mühendislik Fonksiyonları: Taban Dönüşümü, Karmaşık Matematik

Excel'deki mühendislik ailesi, fonksiyon başvurusunun en kolay köşesi gibi okunur. DEC2BIN bir sayıyı ikili (binary) dizeye dönüştürür. HEX2DEC onu geri çevirir. IMSUM iki karmaşık sayıyı toplar. Her biri bir biçimlendirme egzersizi gibi görünür. Ancak öyle değildir. Bu isimlerin arkasında, çoğu geliştiricinin bilgisayar mimarisi dersinden bu yana dokunmadığı on bitlik ikiye tümleyen (two's complement) kodlaması, tamamen dizelerin içinde yaşayan bir karmaşık sayı formatı ve kontrol etmeden önce kaydırırsanız 64 bitlik bir tamsayıyı sessizce taşıracak bitsel (bitwise) operatörler oturur. Excel'i tam olarak kopyalayan bir elektronik tablo motoru bunların hiçbirini yuvarlayamaz

Fonksiyonlar üç gruba ayrılır ve her grup farklı bir tuzağı gizler. Taban dönüşümü negatif sayılar ve taban başına eşiklerle ilgilidir. Karmaşık aritmetik bir dizeyi ayrıştırmak ve biçimlendirmekle ilgilidir. Bitsel işlemler Int64 sınırları içinde kalmakla ilgilidir. Bu makale, HotXLS'in bunları nasıl uyguladığını ve gerçekte yazacağınız çalışma sayfası çağrılarıyla her bir grubu ele almaktadır

Taban dönüşümü ve on bitlik ikiye tümleyen

İleri yön, herkesin beklediği kısımdır. DEC2BIN(9) "1001" verir ve isteğe bağlı ikinci bir argüman sonucu sabit bir genişliğe sol dolgu yapar (left-pads). Tuzak negatif girdidir. Excel bir eksi işareti yazmaz. Değeri hedef tabanda on basamaklı ikiye tümleyen dizesi olarak kodlar, bu nedenle DEC2BIN(-5,10) işareti olan herhangi bir şey yerine "1111111011" döndürür. Değer negatif olduğunda yerler (places) argümanı yoksayılır, çünkü kodlama zaten on basamağa sabitlenmiştir

On basamak sabit bir bütçedir ve bu bütçe taban başına gösterilebilir aralığı belirler. İkilide negatif yarıya geçen büyüklük 512'dir ve sarma modülü (wrap modulus) 1024'tür, bu nedenle bir ikili dize yalnızca tam olarak on karakter uzunluğunda olduğunda ve değeri en az 512 olduğunda işaretli olur. Aynı fikir tabanla ölçeklenir. Sekizli (octal) 2^29'luk bir yarı eşik ve 2^30'luk tam bir modül kullanır. Onaltılı (hexadecimal) 2^39 ve 2^40 kullanır. HotXLS okuyucusu tam olarak bu kuralı uygular: basamakları biriktirir ve yalnızca dize on karakter genişliğindeyken ve birikmiş değer yarı eşiğin üzerinde oturduğunda işaretli değeri kurtarmak için tam modülü çıkarır. Dokuz karakterli bir dize, ne kadar büyük olursa olsun her zaman negatif değildir

Kodlayıcı bunun ayna görüntüsüdür. Negatif olmayan bir değer basamak basamak dönüştürülür ve isteğe bağlı olarak istenen genişliğe sıfırla doldurulur ve tabanın pozitif tavanını taşıyorsa veya istenen genişlik onu tutmak için çok darsa reddedilir. Negatif bir değer, önce tam modül eklenerek aralığa getirilir, bu da onu taban gösterimi her zaman on basamak olan bir değere dönüştürür ve ardından basamaklar genişliği doldurmak için baştaki sıfırlarla yayımlanır. DEC2BIN, DEC2OCT ve DEC2HEX'i kenarlarında birbirleriyle tutarlı tutan şey, tek ortak aralık kontrolü, taban başına simetrik alt ve üst sınırlardır

Bu, fonksiyon adında ondalık sayıdan geçmeden taban değiştiren HEX2BIN ve OCT2HEX gibi çapraz taban dönüşümlerini bırakır. Uygulama her sıralı çift için ayrı bir rutin taşımaz. Girdi dizesini kaynak tabanı kullanarak işaretli bir ondalık değere ayrıştırır, ardından bu ondalık değeri hedef tabana biçimlendirir. Ondalık sayı pivottur. Oluşturulan bir ayrıştırma rutini ve bir biçimlendirme rutini her kombinasyonu kapsar ve her iki yarı da aynı on basamaklı işaretli kuralı paylaştığından, negatif bir değer sağlam işaretiyle yolculuktan sağ çıkar

Karmaşık sayılar dizelerdir, bu nedenle iş ayrıştırmadır

Excel'in karmaşık veri türü yoktur. Karmaşık bir değer "a+bi" dizesidir ve IM ailesindeki her fonksiyon bu dizeleri alır ve bir tane geri verir. COMPLEX dizeyi bir gerçek ve bir sanal bölümden oluşturur. IMSUM, IMSUB, IMPRODUCT ve IMDIV argümanlarını ayrıştırır, sayısal kısımlar üzerinde aritmetiği yapar ve sonucu tekrar bir dizeye biçimlendirir. Sayısal iş lisans cebiridir. Zorluk tamamen metni güvenilir bir şekilde iki kayan noktalı sayıya dönüştürmektir ve işte burada dahili ayrıştırıcı işini yapar

Bu ayrıştırıcıdaki iki ayrıntıyı yanlış anlamak kolaydır. Birincisi çıplak sanal birimdir. "i" dizesi bir çarpı i anlamına gelir, sıfır değil ve bir hata değil, bu nedenle son ekin önündeki katsayı boş olduğunda veya tek bir artı işareti olduğunda ayrıştırıcının onu 1 değeri olarak okuması ve tek bir eksiyi -1 olarak okuması gerekir. Bunu atlayın ve IMSUM("i","i") 2i olmaktan çıkar. İkincisi, gerçek ve sanal bölümleri ayıran işaretle çarpışan bilimsel gösterimdir. Ayrıştırıcı, bir artı veya eksi tarayarak bu ayırıcıyı bulur, ancak "1.5E-3" olarak yazılan bir sayı üsse ait bir eksi içerir. Bu nedenle tarama, hemen önceki karakter e veya E olduğunda artı veya eksiyi ayırıcı olarak ele almayı reddeder. Bu koruma olmadan gerçek kısım üs işaretinde ikiye bölünür ve ayrıştırma mükemmel geçerli girdide başarısız olur

Sonekin kendisi normalleştirilmek yerine korunur. Excel hem i hem de j'yi kabul eder ve HotXLS girdinin hangisini kullandığını hatırlar, böylece biçimlendirilmiş sonuç aynı harfi taşır. Biçimlendirme daha sonra geleneksel kısaltmaları uygular: bir sanal kısım sadece sonek olarak yazdırılır, eksi bir -i olarak, sıfır sanal kısım düz bir gerçek sayıya çöker ve sıfır gerçek kısım öndeki 0+'yı düşürür

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
begin
  Book := TXLSXWorkbook.Create;
  try
    Sheet := Book.Sheets.Add('Engineering');
    // Negatif girdi: on bitlik ikiye tümleyen, yerler argümanı yoksayıldı.
    Sheet.Cells[1, 1].Value := Sheet.Calculate('=DEC2BIN(-5,10)'); // 1111111011
    // İki "a+bi" dizesinde karmaşık çarpım.
    Sheet.Cells[2, 1].Value := Sheet.Calculate('=IMPRODUCT("3+4i","1+2i")'); // -5+10i
  finally
    Book.Free;
  end;
end;

Aralarında IMSQRT, IMEXP, IMLN ve IMPOWER'ın da bulunduğu aşkın karmaşık fonksiyonlar dikdörtgen koordinatlarda çalışmaz. Ayrıştırılmış değeri kutupsal biçime dönüştürürler, işlemi modül ve argüman üzerinde uygularlar ve geri dönüştürürler. Karekök, argümanı yarıya indirir ve modülün kökünü alır. Bir kuvvet, argümanı çarpar ve modülü yükseltir. Bunu başka bir şekilde yapmak, her bir kimliği dikdörtgen biçiminde yeniden türetmek anlamına gelir; bu da hem daha fazla kod hem de dal kesimlerinin (branch cuts) yakınında sayısal olarak daha az kararlıdır

Bitsel operatörler ve ilk kontrol etmeniz gereken taşma

Excel 2013 BITAND, BITOR, BITXOR, BITLSHIFT ve BITRSHIFT ekledi. İşlenenler kısıtlanmıştır: her biri 2^48 eksi 1'den büyük olmayan negatif olmayan bir tamsayı olmalıdır ve herhangi bir kesirli veya negatif argüman sayısal bir hatadır. Bu üst sınır, bir double'ın tam olarak gösterilebilir aralığının çok içinde kalırken herhangi bir gerçekçi bayrak kümesini kapsayacak kadar cömerttir, ki bu önemlidir çünkü Excel her sayısal argümanı bir kayan nokta değeri olarak geçirir

Kaydırma (shift) fonksiyonları gerçekten ısıran tek sıralama kuralını taşır. Sola kaydırma girdisinden çok daha büyük bir değer üretebilir ve önce shl'yi gerçekleştirir ve sonucu daha sonra incelerseniz Int64'ü zaten taşırmışsınızdır ve test anlamsızdır. Kontrolün kaydırmadan önce gelmesi gerekir. HotXLS, işleneni kaydırma miktarına göre sağa kaydırılan tavanla karşılaştırır ve yalnızca işlenen uyarsa gerçek sola kaydırmayı gerçekleştirir. 53 bitin ötesindeki bir kaydırma büyüklüğü tamamen reddedilir ve negatif bir kaydırma yönü tersine çevirir, bu nedenle negatif sayılı BITLSHIFT sağa kaydırma gibi davranır. Prensip bu tek fonksiyonu çok aşarak genelleşir: taşmayı önlemek için bir koruma mevcut olduğunda, korumayı amaçladığı sonuçta değil, girdiler üzerinde çalışmalıdır

// Bitsel çağrılar, Calculate üzerinden aynı şekilde değerlendirilir.
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

Gelecekteki fonksiyonlar ve _xlfn isim öneki

Bitsel operatörler ve 2007 sonrası eklemelerin uzun bir listesi, ne hesapladıklarıyla hiçbir ilgisi olmayan ve Excel'in onları nasıl depoladığıyla her türlü ilgisi olan bir adlandırma şemasıyla etkileşime girer. Orijinal ikili çalışma sayfası biçimi, her yerleşik fonksiyona sabit bir tabloda sayısal bir yuva atadı. Bu tablo dondurulduktan sonra icat edilen fonksiyonların yuvası yoktur. Böyle bir fonksiyonu bir dosyaya kaydetmek ve modern bir Excel'in onu tanımasını sağlamak için ad bir _xlfn. öneki ile yazılır, bu nedenle kullanıcı yalnızca BITAND yazsa da BITAND diskte _xlfn.BITAND olarak saklanır

İşin püf noktası kuralın tek tip olmamasıdır. Bazı yeni fonksiyonlara tablo yuvaları verildi ve çıplak (bare) yazılıyorlar, oysa birkaç eski gizli fonksiyon yaşlarına rağmen ön ek olmadan yazılıyor. HotXLS, hangi isimlerin öneke ihtiyaç duyduğuna dair açık bir beyaz liste tutar, onu yazarken ekler ve okurken çıkarır, böylece ayarladığınız ve geri okuduğunuz formül metni her zaman Excel'e dönük temiz bir isimdir. =BITLSHIFT(5,2) ayarlarsınız, dosya _xlfn.BITLSHIFT tutar ve sonuç ne olursa olsun 20 olarak döner. Önek, kodda çalıştığınız formüllere asla sızmaması gereken bir depolama ayrıntısıdır

Bir çalışma sayfasında bir araya getirmek

Tüm bunlar için açık yüzey (public surface) küçüktür. Bir TXLSXWorkbook oluşturun, bir çalışma sayfası ekleyin ve Cells[Row, Col].Formula aracılığıyla bir hücreye formül yazıp yeniden hesaplayın ya da formülü o sayfaya göre derleyen ve bir Variant döndüren çalışma sayfasının Calculate yöntemiyle doğrudan bir ifadeyi değerlendirin. Yukarıdaki örnekler Calculate kullanıyor çünkü çevreleyen sayfa durumu olmadan tek bir mühendislik çağrısının sonucunu gösteriyor, ancak çalışma kitabı yeniden hesaplandığında aynı fonksiyonlar gerçek hücre formüllerinde aynı şekilde değerlendirilir

Çağrı sitelerini değil, kodlamaları aklınızda tutmalısınız. Bir ikili dize ancak on basamakta ve sadece tabanı için yarı eşiği geçtiğinde işaretlenir. Karmaşık bir sayı metindir, boş bir sanal katsayı birdir ve ayrıştırıcı bir üssün e'sinin üzerinden atlar. Sola kaydırma, kaydırmadan önce kontrol edilir. Bu dört gerçeği doğru anladığınızda mühendislik ailesi sürpriz kaynağı olmaktan çıkar

Kendi alan matematiğinizi aynı motora bağlıyorsanız, bir işleyici kaydetmenin ve değerleri döndürmenin mekanikleri, formül motorunu özel fonksiyonlarla genişletmeye yönelik makalemizde ele alınmıştır ve bu formüllerin hücre adresi yerine sayfalara ismen ulaşması gerektiğinde, tanımlı adlar ve çapraz sayfa formülleriyle ilgili kılavuz, referansların nasıl çözümlendiğini gösterir. Burada açıklanan mühendislik fonksiyonları, bu blogun başka bir yerinde ele alınan okuma, yazma ve hesaplama API'lerinin yanı sıra Delphi ve C++Builder için HotXLS elektronik tablo bileşeninin bir parçası olarak gönderilir