24 Mart 2015 Salı

IEEE 754 ve String'e Çevirme

String'e Çevirme İşlemleri
Bir double veya float tipini string'e çevirme işlemi her zaman bir sürü karmaşıklığı da beraberinde getiriyor. Kullanılan ayraçlar, gösterilen hane sayısı gibi (roundtrip olup olmaması) vs.

Not : IEEE 754 double tipi en fazla 17 küsurat hanesi taşıyabilir.

İkilik String'e Çevirme İşlemleri
Java
Örnek:
long binary = Double.doubleToLongBits(3.14159);
String strBinary = Long.toBinaryString(binary);
Ondalık String'e Çevirme İşlemleri
C
C dilinde float veya double tiplerini string'e çevirme için kullanılan temel metod printf'tir

printf bir variadic metoddur (float için dikkat)
printf bir variadic metod olduğu için float veri tipi her zaman double'a çevirilip metoda parametre olarak geçilir.

%f ile default 6 küsurat hanesi gösterilir
double veya float göstermek için %f kullanılırsa bu seçenek ile default olarak 6 küsurat hanesi gösterilir.

Eğer printf ("%.50f") kullanılırsa 50 küsurat hanesi gösterilir.

%4.2f ile toplam genişlik ve küsurat hanesinin gösterimi
Ayraçlar dahil olmak üzere toplam genişlik ve bu genişliğin 2 tanesinin küsurat olarak kullanılacağı belirtilir. Eğer sayı formatlandıktan sonra toplam genişlik tutturulamadıysa sola 0 eklenebilir.

sol tarafa sıfır ekleme
%04.1f ile ayraçlar dahil olmak üzere 4 karakter yazılır. Bunun 1 tanesi küsurat için kullanılır. Eğer toplam uzunluk 4'ten küçükse - örneğin 2.1 - gibi ise sol tarafa 0 eklenerek uzunluk tamamlanır.

toplam genişlik ve küsürat hanesinin dinamik olarak alma
Buradaki örnekte toplam genişlik ve küsürat genişliği dinamil olarak alınıyor. Toplam genişlik 6 ve küsürat genişliği 2 olarak veriliyor.
printf("%*.*f\n", 6 , 2,2345678.9);

printf için yanlış seçenek kullanılırsa gösterilen değer tanımsızdır
Eğer printf metodua yanlış seçenek kullanılırsa yazılan değerin ne olacağı tanımsızdırC++ union to represent data memory vs C scalar variable type sorusuna verilen cevapta da okunabileceği gibi double yazdırmak için %d seçeneği kullanılırsa 8 byte'ın sadece ilk 4 byte'ı okunur ve beklenenden farklı bir değer gösterilir.

%e ile Üssü Şeklinde Gösterim
Bu gösterim şeklinde "e" veya "E" sembolü kullanılır ve üssü anlamına gelir. Örneğin 1e-9'un anlamı  0.000000001 iken -1e9 'un anlamı -1000000000.0'dur.

%g ile en kısa gösterimin seçilmesi

double değişkenleri yazdırmak için %e ,%E%f%F , %g veya %G seçeneklerinden herhangi birisi kullanılabilir.

%g ile en kısa gösterim şekli seçilir. Dolayısıyla bazen küsürat hanesinde sadece 0 varsa yazılmaz. Örneğin

printf("%g\n",5.0); //Çıktı olarak 5 yazar
printf("%g\n",5.1);//Çıktı olarak 5.1 yazar
%g ile round trip
%17g ile C#'taki gibi round trip string'e çevrim ve tekrar floating pointe çevrim yapılabilir.

%lf ile 80 bitlik long double değişkeninin yazılması

long double değişkenleri yazdırmak için %lf seçeneği kullanılabilir.

C++
C++ streamleri ile küsurat atama
Şu şekilde kullanılır

double pi = 3.14159265359;
stringstream stream;
stream << fixed << setprecision(2) << pi;
string s = stream.str();
1. Eğer azami küsurat isteniyorsa 2 yerine std::numeric_limits<double>::digits10 de kullanılabilir.
2. std::fixed gösterim ile scientific veya default gösterim yerine küsuratlı gösterimin istendiği belirtilir.
3. setprecision kalıcıdır.Bütün floating point gösterimlerini etkiler.

boşlukları doldurma
Şöyle yapılır. Böylece 42 versek bile 42.000000 (toplam 6 sıfır) elde ederiz.
std::cout << std::fixed << std::setw( 11 ) << std::setprecision( 6 ) << my_double;
1. std::setw manipülatorü kalıcı değildir. Bir sonraki << işlemi ile temizlenir.
2. Normalde boşluklar 0 karakteril ile doldurulur. Eğer genişliği doldurmak için bir başka karakter kullanılmak isteniyorsa şöyle yapılır
std::cout << std::fixed << std::setw( 11 ) << std::setprecision( 6 ) 
          << std::setfill( '_' ) << my_double;

boost
boost kütüphanesi de printf'e benzer bazı metodlar sunmaktadır.
#include <boost/format.hpp>
#include <iostream>

int main() {
    double x = 7.40200133400;
    std::cout << boost::format("%1$.16f") % x << "\n";
}
Java
Java'da iki yöntem var. printf ve DecimalFormat.
printf yöntemi
Java C'deki printf'in aynısını kullanıyor.
Printf

Örnekte toplam uzunluğun, küsüratın ve üssü gösterimin kullanılabildiği görülebilir.
Printf formatting examples
Eğer minimum uzunluk yanlış verilmişse MissingFormatWidthException alınır.

System.out.printf("%.7f\n", 1.123456789123456789);
kodu bize

1.1234568
çıktısını verir.
DecimalFormat yöntemi
Örnek
DecimalFormat df = new DecimalFormat("####0.000000");
String result = df.format(1.234);
System.out.println(result);
round trip çevrim
RoundTrip Formatlama yazısına taşıdım.



Hiç yorum yok:

Yorum Gönder