Hoe verkrijg ik de MSB digits van een 32bits getal?
Dit is het getal.

00 86 fd 30

Ik moet naar.

03 75

Decimaal zit het er zo uit.

8846640
885

Wil je binair afronden (de hoogste bits pakken) of delen door 10.000 ? Want zo te zien doe je het laatste.

Op 2 september 2007 16:42:05 schreef JoWi:
Wil je binair afronden (de hoogste bits pakken) of delen door 10.000 ? Want zo te zien doe je het laatste.

Ja het is delen door 10000, maar dan rond ie verkeert af, namelijk op 884, en ik weet niet hoe je kan delen door 10000. (alleen met 16/16, maar dat kost een hoop rekentijd.)
Ik kreeg wel een tip.
(8846640+5000)/10000 = 885. Dus het halve deelgetal eerst erbij optellen.
Een andere manier is de digits eruit halen, dus de MSB digits, maar dan rond ie ook verkeert af, op 884.

Delen door 5000, er 1 bij optellen, delen door 2 (right shift) en dan heb je het afgeronde resultaat.

Voor het delen van een 32bit getal door een 16bit getal is op diverse plaatsen voorbeeldcode te vinden. (voor een PIC o.a. op www.piclist.com). Ik heb nog wel een routine die een 64bit getal deelt door een een 32bit getal, maar dat is overkill)

8846640/5000 zou ik ook zo kunnen doen 8846/5.
Alleen hoe haal ik 3 digits eraf? (delen door 1000)
Dan kom ik ook op 885 uit.

((8846/5)+1)/2=885

Ik weet alleen dat 16*625 = 10000 is.

Welke programmeertaal gebruik je? Ik weet dat sommige uC een deel-instructie hebben waar je op het eind het resultaat in het ene register, en de "rest" in een ander register hebt staan. Aan de hand van die "rest" kun je dan nog een afronding doen.
Maar als je C, basic oid gebruikt, dan heb je daar niks aan natuurlijk.

Op 2 september 2007 20:46:54 schreef flipflop:
Welke programmeertaal gebruik je? Ik weet dat sommige uC een deel-instructie hebben waar je op het eind het resultaat in het ene register, en de "rest" in een ander register hebt staan. Aan de hand van die "rest" kun je dan nog een afronding doen.
Maar als je C, basic oid gebruikt, dan heb je daar niks aan natuurlijk.

Assembleertaal.
Ik heb alleen 8bit registers en een statusregister met 8 flaggen. AVR is Harvard RISC.
Er zijn wel routines voor 16*16 en 16/16, maar die kosten veel cycles, ik zat te denken aan de MSB digits, want die heb ik nodig.

8846640
885

MSB digits lijkt sneller maar dat hangt maar helemaal af van het stelsel waarin je werkt. Als mens kun je snel delen door 10 door het laatste getal weg te halen. Een microcontroller werkt binair dus kan alleen snel delen door 2 door het laatste bit weg te laten (en alle machten ook natuurlijk). Je kan niet een snelle methode in het 10-tallig stelsel zomaar omzetten in binair stelsel.

Vermenigvuldigen en delen zijn nou eenmaal zwaar, als je een ATmega hebt kun je nog redelijk snel vermenigvuldigen. Er is nog een methode om te delen met een vermenigvuldiging, maar of dat in jouw geval sneller is weet ik niet, zeker niet met zulke grote getallen.

Bijvoorbeeld met 32-bits getallen:
x / c = (2^32 / c) * x / 2^32

2^32/c reken je van te voren uit, die constante vermenigvuldig je met x (64-bits resultaat!). Delen door 2^32 kan makkelijk door de laagste 32-bits weg te gooien.

Weet alleen niet of dit altijd 100% het goede antwoord geeft als 2^32/c niet perfect deelt. Bovendien is een 64-bis resultaat nog een hoop voor een AVR en ben je misschien sneller af met een deling.

MSB digits lijkt sneller maar dat hangt maar helemaal af van het stelsel waarin je werkt. Als mens kun je snel delen door 10 door het laatste getal weg te halen. Een microcontroller werkt binair dus kan alleen snel delen door 2 door het laatste bit weg te laten (en alle machten ook natuurlijk). Je kan niet een snelle methode in het 10-tallig stelsel zomaar omzetten in binair stelsel.

Ja er staat eigenlijk.

100001101111110100110000

En dat moet worden.

1101110101

Bijvoorbeeld met 32-bits getallen:
x / c = (2^32 / c) * x / 2^32
2^32/c reken je van te voren uit, die constante vermenigvuldig je met x (64-bits resultaat!). Delen door 2^32 kan makkelijk door de laagste 32-bits weg te gooien.

Ik wil niet naar een 64 bits resultaat. 8 registers.

Wat wel kan is telkens zoveel eraf trekken, dan het aantal keer tellen. (sub32)

8846640 - 1000000 (sub32)

Dat gaat 8x, een 8 in de teller.
Dan heb je dit over.

846640 - 100000 (sub32)

Dat gaat weer 8x volgende 8
Dan over.

46640 - 10000 (sub16)
4x

6640 - 1000 (sub16)
6x

Nu heb je 4 getallen waarvan laatste getal groter dan 5 is, dus 3de getal met 1 ophogen -> 885.
Hiervoor heb je nodig sub32 en sub16, ik geloof dat die routines niet al teveel tijd in beslag nemen. Die sub32 wil ik ook nog vanaf, ik zou op 16bit willen blijven.
Er zijn nog meer manieren mogelijk.