1. Gerçek sayıları yuvarlama

Daha önce tartıştığımız gibi, bir değişkene gerçek bir sayı atandığında int, her zaman en yakın küçük tamsayıya yuvarlanır - kesirli kısım basitçe atılır.

Ancak, kesirli bir sayının her iki yönde de en yakın tamsayıya yuvarlanması veya hatta yukarı yuvarlanması gereken bir durumu hayal etmek kolaydır. Bu durumda ne yaparsın?

Bu ve buna benzer birçok durum için Java , , ve metotlarına Mathsahip bir sınıfa sahiptir .round()ceil()floor()


Math.round()yöntem

Yöntem Math.round(), bir sayıyı en yakın tamsayıya yuvarlar:

long x = Math.round(real_number)

Ancak burada başka bir nüans daha var: bu yöntem bir longtamsayı döndürür (bir değil int). Gerçek sayılar çok büyük olabileceğinden, Java'nın yaratıcıları Java'nın mevcut en büyük tamsayı türünü kullanmaya karar verdiler: long.

Buna göre, bir programcı sonucu bir değişkene atamak istiyorsa int, derleyiciye olası veri kaybını kabul ettiğini açıkça belirtmelidir (sonuçta elde edilen sayının bir türe uymaması durumunda int).

int x = (int) Math.round(real_number)

Örnekler:

İfade Sonuç
int x = (int) Math.round(4.1);
4
int x = (int) Math.round(4.5);
5
int x = (int) Math.round(4.9);
5

Math.ceil()yöntem

Yöntem Math.ceil(), bir sayıyı bir tamsayıya yuvarlar . İşte örnekler:

İfade Sonuç
int x = (int) Math.ceil(4.1);
5
int x = (int) Math.ceil(4.5);
5
int x = (int) Math.ceil(4.9);
5

Math.floor()yöntem

Yöntem Math.floor(), bir sayıyı bir tamsayıya yuvarlar . İşte örnekler:

İfade Sonuç
int x = (int) Math.floor(4.1);
4
int x = (int) Math.floor(4.5);
4
int x = (int) Math.floor(4.9);
4

Tabii ki, bir sayıyı bir tamsayıya yuvarlarken , bir tip atama operatörünü kullanmak daha kolaydır:(int)

İfade Sonuç
int x = (int) 4.9
4

Bu isimleri hatırlamakta zorlanıyorsanız, kısa bir İngilizce dersi yardımcı olacaktır:

  • Mathmatematik demektir
  • Roundyuvarlak demektir
  • Ceilingtavan demek
  • Floorkat anlamına gelir

2. Kayan noktalı sayılar nasıl yapılandırılır?

Tip , ile doublearalığındaki değerleri saklayabilir . Bu geniş değer aralığı (türe kıyasla ), türün ( ve ) tamsayı türlerinden tamamen farklı bir iç yapıya sahip olması gerçeğiyle açıklanır . Dahili olarak, tür, değerini iki sayı olarak kodlar: ilki mantis olarak adlandırılır ve ikincisi üs olarak adlandırılır .-1.7*10308+1.7*10308intdoublefloatdouble

Diyelim ki elimizde bir sayı var 123456789ve onu bir doubledeğişken olarak saklıyoruz. Bunu yaptığımızda, sayı şuna dönüştürülür ve tür dahili olarak iki sayı depolar - ve . Önem ("sayının önemli kısmı" veya mantis) kırmızı renkle vurgulanırken, üs mavi renkle vurgulanır.1.23456789*108double234567898

Bu yaklaşım, hem çok büyük sayıların hem de çok küçük sayıların saklanmasını mümkün kılar. Ancak sayının temsili 8 bayt (64 bit) ile sınırlı olduğundan ve bazı bitler üssü depolamak için kullanıldığından ( ayrıca mantisin işareti ve üssün işareti), mantisi temsil etmek için mevcut olan maksimum basamaklar 15 _ _

Bu , gerçek sayıların nasıl yapılandırıldığının çok basitleştirilmiş bir açıklamasıdır.


3. Gerçek sayılarla çalışırken hassasiyet kaybı

Gerçek sayılarla çalışırken, gerçek sayıların kesin olmadığını her zaman aklınızda bulundurun . Ondalıktan ikiliye dönüştürürken her zaman yuvarlama hataları ve dönüştürme hataları olabilir . Ek olarak, en yaygın hata kaynağı, radikal olarak farklı ölçeklerde sayıları toplarken/çıkarırken kesinlik kaybıdır .

Bu son gerçek, acemi programcılar için biraz akıllara durgunluk veriyor.

Çıkarırsak , elde ederiz .1/109109109

Tamamen farklı ölçeklerde sayıları çıkarma Açıklama
 1000000000.000000000;
-         0.000000001;
 1000000000.000000000;
İkinci sayı son derece küçüktür ve bu, (gri renkle vurgulanan) anlamının göz ardı edilmesine neden olur. 15 önemli basamak turuncu renkle vurgulanmıştır.

Ne diyebiliriz, programlama matematikle aynı şey değildir.


4. Gerçek sayıları karşılaştırırken yaşanan tuzak

Gerçek sayıları karşılaştırırken programcıları bekleyen başka bir tehlike daha vardır. Gerçek sayılarla çalışırken ortaya çıkar, çünkü yuvarlama hataları birikebilir. Sonuç olarak, gerçek sayıların eşit olmasının beklendiği, ancak eşit olmadığı durumlar vardır. Veya tam tersi: sayıların farklı olması beklenir, ancak eşittirler.

Örnek:

İfade Açıklama
double a = 1000000000.0;
double b = 0.000000001;
double c = a - b;
Değişkenin değeri a olacak 1000000000.0
Değişkenin değeri c olacak 1000000000.0
(değişkendeki sayı b aşırı derecede küçük)

Yukarıdaki örnekte ave ceşit olmamalı, ama eşitler.

Veya başka bir örnek verelim:

İfade Açıklama
double a = 1.00000000000000001;
double b = 1.00000000000000002;
Değişkenin değeri a olacak 1.0
Değişkenin değeri b olacak1.0

5. Hakkında ilginç bir gerçekstrictfp

Java, diğer programlama dillerinde bulunmayan özel bir anahtar kelimeye (strictfp katı kayan nokta ) sahiptir. Ve buna neden ihtiyacın olduğunu biliyor musun? Kayan noktalı sayılarla yapılan işlemlerin doğruluğunu kötüleştirir . İşte nasıl ortaya çıktığının hikayesi:

Java'nın yaratıcıları:
Java'nın çok popüler olmasını ve Java programlarını olabildiğince çok cihazda çalıştırmasını gerçekten istiyoruz. Bu nedenle, Java makinesi belirtiminin, tüm programların tüm aygıt türlerinde aynı şekilde çalışması gerektiğini söylediğinden emin olduk!
Intel işlemci üreticileri:
Selam millet! İşlemcilerimizi geliştirdik ve artık tüm gerçek sayılar işlemcilerimizde 8 bayt yerine 10 bayt kullanılarak temsil ediliyor. Daha fazla bayt, daha anlamlı basamaklar anlamına gelir. Bu ne anlama gelir? Bu doğru! Artık bilimsel hesaplamalarınız daha da doğru olacak!
Bilim adamları ve ultra hassas hesaplamalara dahil olan herkes:
Serin! Tebrikler. Mükemmel haberler!
Java'nın yaratıcıları:
Hayır-hayır-hayır çocuklar! Tüm Java programlarının tüm cihazlarda aynı şekilde çalışması gerektiğini size daha önce söylemiştik . Intel işlemcilerde 10 baytlık gerçek sayıları kullanma özelliğini zorla devre dışı bırakacağız.
Şimdi her şey tekrar yolunda! Bize teşekkür etme.
Bilim adamları ve ultra hassas hesaplamalara dahil olan herkes:
Tamamen delirdin mi? Çabucak her şeyi eski haline getirin!
Java'nın yaratıcıları:
Beyler, bu sizin iyiliğiniz için! Bir hayal edin: tüm Java programları, tüm cihazlarda aynı şekilde çalışır . Bu çok havalı!
Bilim adamları ve ultra hassas hesaplamalara dahil olan herkes:
Hayır. Hiç hoş değil. Çabucak her şeyi eski haline getirin! Veya Java'nızı nereye koyacağımızı biliyor musunuz?
Java'nın yaratıcıları:
Hmm. Neden hemen söylemedin? Elbette geri koyacağız.
En son işlemcilerin tüm özelliklerini kullanma yeteneğinizi geri getirdik.
Bu arada... strictfpAnahtar kelimeyi de dile özel olarak ekledik. Bir fonksiyonun adından önce yazarsanız, o fonksiyonun içindeki gerçek sayıları içeren tüm işlemler, tüm cihazlarda eşit derecede kötü olacaktır !