Gå til innhold

[Løst] Beregningsrekkefølge i python, forstår ikke rekkefølgen (nå også inkl. utregninger hvor x er mindre enn y (x%y))


Anbefalte innlegg

Fra nettsiden "Learn Python The Hard Way" (http://learnpythonthehardway.org/book/ex3.html), sliter jeg med å forstå rekkefølgen på hvordan python beregner følgende regnestykke:

print "Rosters", 100 - 25 * 3 % 4

Rett svar er 97.

 

Jeg trodde det ville bli gjort som:

25 * 3 = 75

100 - 75 = 25

25 % 4 =1

Men tok skammelig feil der.

 

(4 % 3) gir 3, denne er jeg med på.

(25 * 3 % 4) gir 3, denne er jeg også med på.

(100 - (25 * 3 % 4)) gir 97, det er jeg med på.

 

Men hvorfor beregnes (%) etter (*) men før (-) ?

 

 

Tydeligvis noe grunnleggende jeg ikke har fått med meg.

Kan noen forklare meg dette?

 

 

Endret av Teza
Lenke til kommentar
Videoannonse
Annonse

http://stackoverflow.com/questions/4729025/modulo-and-order-of-operation-in-python-zed-shaw-examples

http://docs.python.org/2/reference/expressions.html#operator-precedence

 

Både * og % har høgare prioritet enn -, og vert evaluert før. * og % har same prioritet, so det leddet vert evaluert frå venstre mot høgre, fyrst ganginga, so modulo.

Endret av Torbjørn T.
Lenke til kommentar

Standard aritmetisk rekkefølge. Multiplikasjon og divisjon før addisjon og subtraksjon; ellers venstre til høyre. Eneste overraskelsen er modulo som ikke eksisterer som en egen operasjon i grunnskolematematikk (så veldig overraskende er det dog ikke, siden det har med divisjon å gjøre).

Lenke til kommentar

(4 % 3) gir 3, denne er jeg med på.

 

Så feil kan jeg ta om min egen påstand!

først og fremst var dette en skrivefeil, skulle være 3%4 er lik 3.

Tanken min var at 3/4=0.75 og at dette utgjorde 3 deler av 4.

Jeg kom dog fort ut på tynn is når jeg begynte å bytte på tallene.

 

Håper denne beskrivelsen jeg har basert meg på, er den riktige i alle situasjoner:

# -*- coding: utf-8 -*-
# Modulo (x == (x/y)*y + (x%y)) prioritet i regnestykker

print 25 % 4 
# returnerer verdien 1 
# 25/4=6.25, 6*4=24, 25-24=1

print 5 * 5 % 4 
# returnerer verdien 1
# 5*5=25, 25/4= 6.25, 6*4=24, 25-24=1

print 100 / 4 % 4 
# returnerer verdien 1
# 100/4=25, 25/4= 6.25, 6*4=24, 25-24=1

print 4 % 4 
# ingen restverdi

print 3 % 4
# returnerer verdien 3
# (x/y)*y, 3/4=0,75, 0,75*4=3, 

print 2 % 4
# returnerer verdien 2
# (x/y)*y, 2/4=0,5, 0,5*4=2

print 1 % 4
# returnerer verdien 1
# (x/y)*y, 1/4=0,25, 0,25*4=1

print 0.5 % 4
# returnerer verdien 0,5
# (x/y)*y, 0,5/4=0,125, 0,125*4=0,5
# alle verdier mindre enn 1, returneres som de er

print 0 % 4 
# returnerer verdien 0

print -2 % 4
# returnerer verdien 2

print -4 % 4
# ingen restverdi

print -6 % 4
# returnerer verdien 2
# (-6/4)=(-1,5), 1*(-4)=(-4), (-6)-(-4)=(-2)
Endret av Teza
Lenke til kommentar

 

 

Så feil kan jeg ta om min egen påstand!

først og fremst var dette en skrivefeil, skulle være 3%4 er lik 3.

Tanken min var at 3/4=0.75 og at dette utgjorde 3 deler av 4.

Jeg kom dog fort ut på tynn is når jeg begynte å bytte på tallene.

 

Håper denne beskrivelsen jeg har basert meg på, er den riktige i alle situasjoner:

#Snipp

Kunne evt brukt assert isteden for print i scriptet ditt.

 

f.eks

assert 25 % 4 == 1

Endret av JuletreDuden
Lenke til kommentar

Modulo er svært likt divisjon, jeg skal prøve å forklare hvordan det funker - og det starter med heltallsdivisjon slik du lærte det på barneskolen.

 

Når man skulle sette opp dele-stykker på barneskolen gjorde vi noe lignende dette:

 

La oss si du skal ta 1852 å dele på 4, da kan du gjøre det trinnvis slik som dette:

0dc6731de53dac7b120ba29147eef4c3518d2422

Vi kan ikke dele 1 på 4.
Da tar vi neste siffer...
18 : 4 = 4 med 2 som rest

Vi trekker ned sifferet 5 i 1852 og dividerer 25 på 4.
8123378cc756d05139d3aa09f0542efb518d2423


25 : 4 = 6 med 1 til rest

Vi trekker ned sifferet 2, det siste sifferet i 1852, og dividerer 12 på 4.
7e2860ad7f217bbdc50f967ffd5b9515518d2423

12 : 4 = 3

Her går stykket opp og man får at 1852 / 4 = 463 - Men hva med tilfeller der dette ikke går opp? La oss si man ønsker å dele 9826 på 6, og få heltall til svar. (f.eks. om du var 6 mennesker som skulle spleise på en tur til 9826, hvor alle betaler like mye. Men siden vi ikke lenger har "50-øringer" må man ta seg til rette med nærmeste krone)

a978910cba4606787e7f9367bc01c778518d2423

Her ser man at man ender opp med at svaret er 1637, med 3 i rest. Disse 3 i rest vil da symbolisere det som mangler. Hvis alle betaler 1637 kroner hver for turen vil dere ha betalt 3 kroner for lite, men om alle betaler 1638 for turen så har dere betalt for mye.

Rest er altså "det som mangler" etter man har funnet dette heltallet.

 

ser her for en bedre forklaring:

http://www.matematikk.org/artikkel.html?tid=67617

 

Så hva er da modudlo? Jo, modulo er denne resten. Når man regner med modulo er man alstå ikke innteresert i svaret på divisjonen - men heller hvor mye man sitter igjen med.

 

9 / 3 = 3 med 0 i rest - (9 % 3 = 0)
10 / 3 = 3 med 1 i rest (10 % 3 = 1)
11 / 3 = 3 med 2 i rest (11 % 3 = 2)

12 / 3 = 4 med 0 i rest (12 % 3 = 0)

Men ja, dette kan regnes på følgende måte:
x % y = (x / y) * x
Gitt at du her kun bruker heltall, og sløyfer alle siffer etter komme ved divisjon.

Endret av etse
Lenke til kommentar

Men ja, dette kan regnes på følgende måte:

x % y = (x / y) * x

Jeg aner ikke hvordan du får det der til å fungere...

mod = ((x / y) - floor(x / y)) * y ... I python så vil dette altså kreve at enten x, eller y er flytepunkt.

 

 

Med den formelen så kan vi lage dette eksempelet:

from math import floor

def mod(x,y):
  d = x / float(y);
  return (d - floor(d)) * y;

//Eller kortere variant, men mer kalkulasjon:
def mod2(x,y):
  return ((x / float(y))-(x // y)) * y

print [mod2(10,-3.6),  10 % -3.6]
print [mod2(-10, 6),   -10 % 6]
print [mod2(27, 2),    27 % 2]

Dette er funksjonen jeg bruker for å oppnå pythons modulus-funksjon når jeg programmerer i C eller Delphi.

 

Nå er det sansynligvis billigere måter å gjøre dette på, men fungerer fint for meg.

 

Endret av warpie
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...