Kayan Nokta Sayısını En Yakın Tam Sayıya Yuvarlama?


128

Başlıktan da anlaşılacağı gibi, bir kayan noktalı sayı alıp en yakın tam sayıya yuvarlamak istiyorum. Bununla birlikte, eğer bir bütün değilse, bir sonraki tam sayıya ne kadar yakın olursa olsun, HER ZAMAN değişkeni aşağı yuvarlamak istiyorum. Bunu yapmanın bir yolu var mı?


2
Muhtemel bir zorluk, IEEE kayan nokta formatlarının büyüklük 1'den büyük olacak kadar büyük sayıları temsil edebilmesidir. Böylece, x'i aşağı yuvarlarken x + 1'i aşağı yuvarlamak size beklediğiniz sonucu vermeyecektir.
dmckee --- eski moderatör kedicik

Lütfen bazı örnekler gönderin.
Ashwini Chaudhary

Yanıtlar:


179

Basit

print int(x)

de çalışacak.


7
int (0.6) = 1 yerine 0
Helin Wang

39
@HelinWang Tam olarak OP'nin istediği buydu.
Petr Peller

5
Bu, en Pythonic yaklaşım gibi görünüyor.
Gyan Veda

23
Bu pozitif sayılar için işe yarar, ancak negatif sayılar yuvarlanacaktır:int(-23.3) == 23
Alex Riley

2
600851475143 gibi tamsayı aralığının ötesindeki sayılar için çalışmazsa, temelde bir bellek hatasını işaretler.
Muyide Ibukun

77

Bunlardan biri çalışmalıdır:

import math
math.trunc(1.5)
> 1
math.trunc(-1.5)
> -1
math.floor(1.5)
> 1
math.floor(-1.5)
> -2

14
Çıktısı math.truncbir tamsayı, çıktısı math.floorise float'tır.
evedovelli

6
@evedovelli: Artık pek değil. type(math.floor(1.51)) -> intve type(math.trunc(1.51)) -> intitibariylepython 3.6.0
SKPS

4
Bu seçenekler "int (x)" den daha belirgindir ve dolayısıyla daha Pythonictir.
Tristan

44
x//1

//Operatör bölünme kat döndürür. 1'e bölmek numaranızı değiştirmediğinden, bu taban değerine eşdeğerdir ancak içe aktarmaya gerek yoktur. Notlar:

  1. Bu bir kayan nokta döndürür
  2. Bu, -∞'a doğru yuvarlanır

Güzel bir ek. int(-1.1) == -1ise -1.1//1 == -2.0ancak decimal.Decimal('-1.1')//1 == decimal.Decimal('-1')(belgelendiği gibi, iddia 2 için geçerli değildir decimal), bu yüzden nasıl güvenerek //boğulan bir tam kararlı, bugün bile değil.
Tino

28

Kayan nokta sonucunu elde etmek için şunu kullanın:

round(x-0.5)

Negatif sayılar için de işe yarar.


6
son derece sofistike yani
Alon


9

birçok insan kullanmam gerektiğini söylüyor int(x)ve bu çoğu durumda iyi çalışıyor, ancak küçük bir sorun var. OP'nin sonucu:

x = 1.9999999999999999

dönecek

x = 2

16. 9'dan sonra tur atacak. Böyle bir şeye asla rastlamayacağınızdan eminseniz, bu büyük bir mesele değil. Ama akılda tutulması gereken bir şey.


17
Bunun nedeni 1.9999999999999999, 2.0dahili float64 gösteriminde aslında eşit olmasıdır. I. e. 64 bitlik kayan nokta bu kadar önemli basamağı temsil edemeyeceğinden, bir float olarak ayrıştırılır çözülmez zaten yuvarlanmıştır. Bunu değerlendirerek doğrulayabilirsiniz 1.9999999999999999 == 2.0. Ve eşittir işleminin kayan sayılarda bir miktar yuvarlama yaptığından şüpheleniyorsanız, ikili gösterimi struct.pack("d", 1.9999999999999999) == struct.pack("d", 2.0)de eşit olan ile karşılaştırabilirsiniz .
blubberdiblub

4
Ve tam olarak senin amacın buysa, neyin yanlış olduğunu anlamıyorum int(). Değer zaten 2.0 ve mutlu bir şekilde 2'ye dönüştürecek.
blubberdiblub

1
OP'nin (veya bunu gelecekte okuyan kişi) amacı, en yakın tamsayıyı (ve yuvarlama değerini değil) herhangi bir nedenle kullanmaksa, akılda tutulması gereken bir şey olacaktır.
lokilindo

3
@lokilindo Ancak bunun hiçbir ilgisi yoktur int(), yalnızca, derleme zamanında yuvarlandığı gibi ( yürütme zamanında çağrılırken) yanlış kullanımıylafloat ilgisi vardır . Değişken için doğru veri türünü kullanırsanız, her şey beklendiği gibi çalışır: verir1.99999999999999992.0 int()int(decimal.Decimal('1.9999999999999999999999999999999999999999999999999999999'))1
Tino

6

Matematiği içe aktarmak istemiyorsanız, şunu kullanabilirsiniz:

int(round(x))

İşte bir belge parçası:

>>> help(round)
Help on built-in function round in module __builtin__:

round(...)
    round(number[, ndigits]) -> floating point number

    Round a number to a given precision in decimal digits (default 0 digits).
    This always returns a floating point number.  Precision may be negative.

Cevabınız için teşekkürler. Bir dahaki sefere doğru kod yazarsanız (parantezleri kapatın) ve bazı belgeler verirseniz daha iyi bir sinyal alacaksınız.
Geoff

2
roundbir yıl önce bu soru sorulduğunda zaten tartışılmış ve cevap olarak reddedilmişti. OP istiyor math.floor.
Adam Smith

3

Numpy ile çalışıyorsanız, negatif sayılarla da çalışan aşağıdaki çözümü kullanabilirsiniz (aynı zamanda diziler üzerinde de çalışır)

import numpy as np
def round_down(num):
    if num < 0:
        return -np.ceil(abs(num))
    else:
        return np.int32(num)
round_down = np.vectorize(round_down)

round_down([-1.1, -1.5, -1.6, 0, 1.1, 1.5, 1.6])
> array([-2., -2., -2.,  0.,  1.,  1.,  1.])

mathModül yerine sadece modülü kullanırsanız da işe yarayacağını düşünüyorum numpy.


1

Bunu çözdün mü bilmiyorum, ama ben sadece bu soruyla karşılaşıyorum. Ondalık noktalardan kurtulmak istiyorsanız, int (x) kullanabilirsiniz ve tüm ondalık basamakları ortadan kaldıracaktır. Round (x) kullanmaya gerek yoktur.


1

Sadece yuvarlayın (x-0.5), bu her zaman Float'unuzun sonraki yuvarlanmış Tamsayı değerini döndürecektir. Do round ile de kolayca yuvarlayabilirsiniz (x + 0.5)


-1

Çok basit olabilir, ama bunu eksi 1'den sonra yuvarlayamaz mısın? Örneğin:

number=1.5
round(number)-1
> 1

4
Bu tam sayılar için yanlış cevabı verir. Örneğin, 2.0 yuvarlama 2'dir ve 1'i çıkarırsanız yanlış sonuç 1 alırsınız.
Pascal Cuoq

@PascalCuoq Sorununuzu anlamıyorum. Sonuç olarak 1.0 istiyor musunuz? Çünkü OP açıkça yuvarlamak istedi ve ardından numarayı en yakına yuvarladı integer.
bad_keypoints

1
@bad_keypoints OP'nin 2.0'ı 1'e yuvarlamak istediğini sanmıyorum.
Pascal Cuoq

@PascalCuoq üzgünüm, az önce olduğumuz yorum dizisindeki cevaba baktım.
bad_keypoints

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.