Di Python de bi “dor” û “Decimal.quantize” deh û hejmar

Dikan

Ya jêrîn rave dike ka meriv çawa di Python de jimare bi dorkirin an dorvekirina jimareyek zewacê tê dor kirin. Jimar tê texmîn kirin ku ji celebê float xala herikîn an jî jimareya yekjimar in.

  • fonksiyona çêkirî (mînak di zimanê bernamekirinê de):round()
    • Dehjimaran bi her jimareya reqeman ve bizivirînin.
    • Hejmarên bêkêmasî li her hejmarek jimareyan bigerin.
    • round() li jimareke zewacê digere, ne li dorberek hevpar
  • pirtûkxaneya standarddecimalquantize()
    • DecimalÇêkirina objeyekê
    • Dorkirina jimareyan li her jimareyekê û dorkirina jimareyan
    • Dorkirina jimareyan li her jimareya jimareyan û dorkirina jimareyan
  • Fonksiyonek nû diyar bike
    • Dehjimaran bi her jimare reqeman bicivînin.
    • Hejmarên bêkêmasî li her hejmarek jimareyan bigerin
    • Nîşe: Ji bo nirxên neyînî

Bala xwe bidinê ku, wekî ku li jor hatî behs kirin, dorhêla fonksiyonê ya çêkirî ne dorvegerek gelemperî ye, lê dorpêkek berbi jimareyek zewacê ye. Ji bo hûragahiyan li jêr binêrin.

fonksiyona çêkirî (mînak di zimanê bernamekirinê de):round()

Round() wekî fonksiyonek çêkirî tête peyda kirin. Ew dikare bêyî importkirina tu modulan were bikar anîn.

Argumana yekem jimareya orîjînal e, û argumana duyemîn jî hejmara reqeman e (ku çend reqeman werin dor kirin).

Dehjimaran bi her jimareya reqeman ve bizivirînin.

Ya jêrîn mînakek pêvajoyê ya ji bo celebê float-xala hêlînê ye.

Ger argumana duyemîn ji holê were rakirin, ew bi hejmareke tevahî tê dorpêç kirin. Tîp jî dibe tîpeke întjimar.

f = 123.456

print(round(f))
# 123

print(type(round(f)))
# <class 'int'>

Ger argumana duyemîn were diyar kirin, ew celebek float-xala hêlînê vedigerîne.

Ger jimareyek erênî were diyar kirin, cihê dehiyê tê diyar kirin; heke jimareyek negatîf were diyar kirin, cîhê yekjimar tê diyar kirin. -1 li dora dehemîn ya herî nêzîk, -2 geryan li sedemîna herî nêzîk, û 0 geryan li yekjimarek (cihê yekem) vedigerîne, lê celebek float vedigerîne, berevajî dema ku jê tê derxistin.

print(round(f, 1))
# 123.5

print(round(f, 2))
# 123.46

print(round(f, -1))
# 120.0

print(round(f, -2))
# 100.0

print(round(f, 0))
# 123.0

print(type(round(f, 0)))
# <class 'float'>

Hejmarên bêkêmasî li her hejmarek jimareyan bigerin.

Li jêr mînakek pêvajoyek ji bo tîpa intjimara yekjimar e.

Ger argumana duyemîn ji holê bê rakirin, an heke 0 an jimareyek erênî were destnîşan kirin, nirxa orîjînal wekî ku heye tê vegerandin. Ger jimareyek negatîf were diyar kirin, ew li ser jimareya yekjimar a têkildar tê dorve kirin. Di her du rewşan de, celebek int-hejmarek tê vegerandin.

i = 99518

print(round(i))
# 99518

print(round(i, 2))
# 99518

print(round(i, -1))
# 99520

print(round(i, -2))
# 99500

print(round(i, -3))
# 100000

round() li jimareke zewacê digere, ne li dorberek hevpar

Bala xwe bidinê ku bi fonksiyona dor()-ya çêkirî ya di Python de 3 dor li jimareyek zewacê digire, ne li dorberek gelemperî.

Wekî ku di belgeya fermî de hatî nivîsandin, 0.5 bi 0 ve tête dorpêç kirin, 5 bi 0 ve tête dorpêç kirin, û hwd.

print('0.4 =>', round(0.4))
print('0.5 =>', round(0.5))
print('0.6 =>', round(0.6))
# 0.4 => 0
# 0.5 => 0
# 0.6 => 1

print('4 =>', round(4, -1))
print('5 =>', round(5, -1))
print('6 =>', round(6, -1))
# 4 => 0
# 5 => 0
# 6 => 10

Pênasekirina dorkirina jimareke zewacê wiha ye.

Ger perçe ji 0,5 kêmtir be, wê li jêr dorpêç bikin; heke perçe ji 0,5 mezintir be, wê bizivirînin; heke perçe tam 0,5 be, wê heta jimareya zewacê ya di navbera dorvekirina jêr û jor de bizivirînin.
Rounding – Wikipedia

0.5 her gav nayê qut kirin.

print('0.5 =>', round(0.5))
print('1.5 =>', round(1.5))
print('2.5 =>', round(2.5))
print('3.5 =>', round(3.5))
print('4.5 =>', round(4.5))
# 0.5 => 0
# 1.5 => 2
# 2.5 => 2
# 3.5 => 4
# 4.5 => 4

Di hin rewşan de, danasîna dorpêkirina jimareyek zewacê jî ji bo pêvajoyên piştî du deh dehiyan derbas nabe.

print('0.05 =>', round(0.05, 1))
print('0.15 =>', round(0.15, 1))
print('0.25 =>', round(0.25, 1))
print('0.35 =>', round(0.35, 1))
print('0.45 =>', round(0.45, 1))
# 0.05 => 0.1
# 0.15 => 0.1
# 0.25 => 0.2
# 0.35 => 0.3
# 0.45 => 0.5

Ev ji ber vê yekê ye ku dehjimar nikarin tam wekî hejmarên xala herikîn, wekî ku di belgeyên fermî de hatine destnîşan kirin, bêne destnîşan kirin.

Tevliheviya dora () ji bo hejmarên xala herikîn dikare we şaş bike:Mînakî, dora (2.675, 2) dê li şûna 2.68 wekî ku tê hêvî kirin 2.67 bide we. Ev ne xeletiyek e.:Ev encama wê yekê ye ku piraniya dehjimaran tam bi hejmarên xala herikandinê nayên temsîl kirin.
round() — Built-in Functions — Python 3.10.2 Documentation

Ger hûn dixwazin bigihîjin dorvekirina giştî an dorvekirina rast a dehiyan heya jimaran, hûn dikarin quantîzasyona dehiyê ya standard a pirtûkxaneyê (li jêr tê diyar kirin) bikar bînin an fonksiyonek nû diyar bikin.

Di heman demê de bala xwe bidin ku dora () di Python 2-ê de ne li jimareyek zewacê ye, lê dor tê.

quantize() ya pirtûkxaneya standard ya dehan

Modula dehiyê ya pirtûkxaneya standard dikare were bikar anîn da ku jimareyên xala hejandina dehiyê ya rastîn bi rê ve bibe.

Bi karanîna rêbaza quantize() ya modula dehek, gengaz e ku bi diyarkirina moda dorpêçkirinê ve hejmaran dor bikin.

Nirxên destnîşankirî yên ji bo dorkirina argumana rêbaza quantize() bi rêzdarî van wateyên jêrîn hene.

  • ROUND_HALF_UP:Girêdana giştî
  • ROUND_HALF_EVEN:Bi jimareyên zewacê ve dor kirin

Modula dehan pirtûkxaneyek standard e, ji ber vê yekê sazkirina zêde ne hewce ye, lê îthalkirin hewce ye.

from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_EVEN

Çêkirina tiştekî Dehanî

Dehanî() dikare ji bo afirandina tiştên bi tîpa Dehanî were bikar anîn.

Ger hûn celebek float wekî arguman destnîşan bikin, hûn dikarin bibînin ka nirx bi rastî wekî çawa tête derman kirin.

print(Decimal(0.05))
# 0.05000000000000000277555756156289135105907917022705078125

print(type(Decimal(0.05)))
# <class 'decimal.Decimal'>

Wekî ku di nimûneyê de tê xuyang kirin, 0.05 bi tam 0.05 nayê derman kirin. Sedema vê yekê ye ku fonksiyona çêkirî ya dora () ku li jor hatî destnîşan kirin, ji bo nirxên dehîkî yên ku di nav nimûneyê de 0.05 jî tê de ne, ji nirxek cûda ji ya ku dihat hêvî kirin tê dorpêç kirin.

Ji ber ku 0.5 yek-nîv e (-1 hêza 2), ew dikare tam bi nîşana binaryê were diyar kirin.

print(Decimal(0.5))
# 0.5

Ger hûn li şûna tîpa float tîpa rêzê diyar bikin, ew ê wekî celebê Dehanî ya nirxa rast were hesibandin.

print(Decimal('0.05'))
# 0.05

Dorkirina jimareyan li her jimareyekê û dorkirina jimareyan

Banga quantize() ji hêmanek bi tîpa Dehanî bikin da ku nirxê dorpêç bikin.

Argumana yekem a quantize() rêzikek bi heman hejmara reqeman e ku hejmara reqemên ku hûn dixwazin bibînin, wek ‘0,1’ an ‘0,01’.

Wekî din, argumana ROUNDING moda dorpêçkirinê diyar dike; ger ROUND_HALF_UP were diyar kirin, dorvekirina giştî tê bikar anîn.

f = 123.456

print(Decimal(str(f)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
# 123

print(Decimal(str(f)).quantize(Decimal('0.1'), rounding=ROUND_HALF_UP))
# 123.5

print(Decimal(str(f)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 123.46

Berevajî fonksiyona çêkirî ya dora (), 0.5 li 1-ê tê dorve kirin.

print('0.4 =>', Decimal(str(0.4)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
print('0.5 =>', Decimal(str(0.5)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
print('0.6 =>', Decimal(str(0.6)).quantize(Decimal('0'), rounding=ROUND_HALF_UP))
# 0.4 => 0
# 0.5 => 1
# 0.6 => 1

Ger dorkirina argûman li ROUND_HALF_EVEN were danîn, dorkirin li jimarên zewacê tê kirin wekî di fonksiyona çêkirî ya dora ().

Wekî ku li jor hatî behs kirin, heke celebek float-xala hêlînê wekî argumana Dehanî () were destnîşan kirin, ew wekî tiştek Dehanî bi nirxek bi nirxa rastîn a celebê float re tê hesibandin, ji ber vê yekê encama karanîna quantize() rêbaz dê ji ya ku tê hêvîkirin cûda be, mîna fonksiyona çêkirî ya dora().

print('0.05 =>', round(0.05, 1))
print('0.15 =>', round(0.15, 1))
print('0.25 =>', round(0.25, 1))
print('0.35 =>', round(0.35, 1))
print('0.45 =>', round(0.45, 1))
# 0.05 => 0.1
# 0.15 => 0.1
# 0.25 => 0.2
# 0.35 => 0.3
# 0.45 => 0.5

print('0.05 =>', Decimal(0.05).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.15 =>', Decimal(0.15).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.25 =>', Decimal(0.25).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.35 =>', Decimal(0.35).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.45 =>', Decimal(0.45).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
# 0.05 => 0.1
# 0.15 => 0.1
# 0.25 => 0.2
# 0.35 => 0.3
# 0.45 => 0.5

Ger argumana Dehanî () wekî rêzika tîpa str were destnîşan kirin, ew wekî objektek Dehanî ya tam wê nirxê tê hesibandin, ji ber vê yekê encam wekî ku tê hêvî kirin e.

print('0.05 =>', Decimal(str(0.05)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.15 =>', Decimal(str(0.15)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.25 =>', Decimal(str(0.25)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.35 =>', Decimal(str(0.35)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
print('0.45 =>', Decimal(str(0.45)).quantize(Decimal('0.1'), rounding=ROUND_HALF_EVEN))
# 0.05 => 0.0
# 0.15 => 0.2
# 0.25 => 0.2
# 0.35 => 0.4
# 0.45 => 0.4

Ji ber ku 0.5 dikare ji hêla celebê float ve rast were hilanîn, di destnîşankirina celebê float de wekî argumana Dehanî() dema ku li jimareyek tevde were dorpêkirin, pirsgirêk tune ye, lê gava ku meriv li cîhek dehek were dorpêkirin, danasîna celebê str ewletir e.

Mînakî, 2.675 bi rastî 2.67499 e …. di celebê float de. Ji ber vê yekê, heke hûn dixwazin du reqalên dehiyê dor bikin, divê hûn rêzek ji Dehanî () re diyar bikin, wekî din dê encam ji encama hêvîkirî cûda be, gelo hûn li dora jimareya herî nêzîk (ROUND_HALF_UP) an jî jimareyek zewacê (ROUND_HALF_EVEN). ).

print(Decimal(2.675))
# 2.67499999999999982236431605997495353221893310546875

print(Decimal(2.675).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 2.67

print(Decimal(str(2.675)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP))
# 2.68

print(Decimal(2.675).quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN))
# 2.67

print(Decimal(str(2.675)).quantize(Decimal('0.01'), rounding=ROUND_HALF_EVEN))
# 2.68

Bala xwe bidinê ku rêbaza quantize() jimareyek tîpek Dehanî vedigerîne, ji ber vê yekê heke hûn dixwazin li ser jimareyek celebek float bixebitin, pêdivî ye ku hûn bi karanîna float() wê veguherînin celebek float, wekî din dê xeletiyek çêbibe.

d = Decimal('123.456').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)

print(d)
# 123.46

print(type(d))
# <class 'decimal.Decimal'>

# print(1.2 + d)
# TypeError: unsupported operand type(s) for +: 'float' and 'decimal.Decimal'

print(1.2 + float(d))
# 124.66

Dorkirina jimareyan li her jimareya jimareyan û dorkirina jimareyan

Heke hûn dixwazin jimareyek yekjimar bizivirînin, wekî argumana yekem tiştek wekî ’10’ diyar bikin dê encama xwestinê nede we.

i = 99518

print(Decimal(i).quantize(Decimal('10'), rounding=ROUND_HALF_UP))
# 99518

Ev ji ber ku quantize() li gora nîşana bireserê Dehanî dorvegerê pêk tîne, lê nîşana Dehanî(’10’) 0 ye, ne 1.

Hûn dikarin bi karanîna E-yê wekî rêzika nîşanderê (mînak, ‘1E1’) nîşanek keyfî diyar bikin. Pêşniyara nîşanan dikare bi rêbaza as_tuple were kontrol kirin.

print(Decimal('10').as_tuple())
# DecimalTuple(sign=0, digits=(1, 0), exponent=0)

print(Decimal('1E1').as_tuple())
# DecimalTuple(sign=0, digits=(1,), exponent=1)

Weke ku ew e, encam dê di nîşana nîşankirinê de bi karanîna E-yê be. Heke hûn dixwazin nîşana normal bikar bînin, an heke hûn dixwazin piştî dorpêçkirinê bi tîpa int-ê tevbigerin, ji bo veguheztina encamê int() bikar bînin.

print(Decimal(i).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP))
# 9.952E+4

print(int(Decimal(i).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
# 99520

print(int(Decimal(i).quantize(Decimal('1E2'), rounding=ROUND_HALF_UP)))
# 99500

print(int(Decimal(i).quantize(Decimal('1E3'), rounding=ROUND_HALF_UP)))
# 100000

Ger dorkirina argumanê li ser ROUND_HALF_UP were danîn, dorpêdana gelemperî dê çêbibe, mînakî, 5 dê bibe 10.

print('4 =>', int(Decimal(4).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
print('5 =>', int(Decimal(5).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
print('6 =>', int(Decimal(6).quantize(Decimal('1E1'), rounding=ROUND_HALF_UP)))
# 4 => 0
# 5 => 10
# 6 => 10

Bê guman, heke hûn wê wekî rêzek diyar bikin pirsgirêk tune.

Fonksiyonek nû diyar bike

Rêbaza karanîna modula dehek rast û ewledar e, lê heke hûn ji veguheztina celebê ne rehet in, hûn dikarin fonksiyonek nû diyar bikin da ku bigihîjin dorpêdana gelemperî.

Gelek awayên gengaz hene ku meriv vê yekê bikin, wek nimûne, fonksiyona jêrîn.

def my_round(val, digit=0):
    p = 10 ** digit
    return (val * p * 2 + 1) // 2 / p

Heke hûn ne hewce ne ku jimara jimareyan diyar bikin û her gav li cîhê dehek yekem bizivirin, hûn dikarin formek hêsantir bikar bînin.

my_round_int = lambda x: int((x * 2 + 1) // 2)

Heke hûn hewce ne rast bin, ew ewletir e ku hûn dehan bikar bînin.

Ya jêrîn tenê ji bo referansê ye.

Dehjimaran bi her jimare reqeman bicivînin.

print(int(my_round(f)))
# 123

print(my_round_int(f))
# 123

print(my_round(f, 1))
# 123.5

print(my_round(f, 2))
# 123.46

Berevajî dor, 0.5 li gorî dorpêkirina gelemperî dibe 1.

print(int(my_round(0.4)))
print(int(my_round(0.5)))
print(int(my_round(0.6)))
# 0
# 1
# 1

Hejmarên bêkêmasî li her hejmarek jimareyan bigerin

i = 99518

print(int(my_round(i, -1)))
# 99520

print(int(my_round(i, -2)))
# 99500

print(int(my_round(i, -3)))
# 100000

Berevajî dor, 5 li gorî dorpêkirina hevpar dibe 10.

print(int(my_round(4, -1)))
print(int(my_round(5, -1)))
print(int(my_round(6, -1)))
# 0
# 10
# 10

Nîşe: Ji bo nirxên neyînî

Di fonksiyona mînaka li jor de, -0.5 bi 0-ê tê dorpêç kirin.

print(int(my_round(-0.4)))
print(int(my_round(-0.5)))
print(int(my_round(-0.6)))
# 0
# 0
# -1

Gelek awayên ramanê li ser dorpêkirina nirxên neyînî hene, lê heke hûn dixwazin -0.5-ê bikin -1, hûn dikarin wekî jêrîn biguherînin, mînakî.

import math

def my_round2(val, digit=0):
    p = 10 ** digit
    s = math.copysign(1, val)
    return (s * val * p * 2 + 1) // 2 / p * s

print(int(my_round2(-0.4)))
print(int(my_round2(-0.5)))
print(int(my_round2(-0.6)))
# 0
# -1
# -1