avr-libc-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] [bugs #11396] Large number jumps to hyperspace


From: Joerg Wunsch
Subject: Re: [avr-libc-dev] [bugs #11396] Large number jumps to hyperspace
Date: Thu, 30 Dec 2004 20:59:34 +0100
User-agent: Mutt/1.4.2.1i

As Russell Shaw wrote:

> >>> uint16_t baud=9600
> >>> uint16_t reg=16000000/(16*baud) - 1;

> >what about __udivmodsi4?

Yeah.  I didn't assume such poor optimization.

> In the real code, uint16_t baud was set at 9600 using a const
> literal passed as an array parameter.

As Eric just closed the bug report as being unreproducible, I gave it
a try to simulate your example code.  I cannot reproduce any ``jumps
to nowhere'' behaviour though (and thus basically confirm Eric's
judgement).

However, your above example miscalculates `reg', as the expression
``16*baud'' is computed in uint16_t domain but overflows it.  The
result of this subexpression is 153600 but is truncated to 22528.
Maybe this is your problem?

Rewriting the second calculation as:

uint16_t reg=16000000/(16*(unsigned long)baud) - 1;

makes it work for me.  Though this is technically right, I think
most people would prefer

uint16_t reg=16000000UL/(16*(unsigned long)baud) - 1;

instead to make it explicit that the clock frequency is also an
unsigned long (even though the C standard is on your side and you're
permitted to omit the `UL').  Writing the UL suffix is also sufficient
to force the entire expression into the UL domain, so this works, too:

uint16_t reg=16000000UL/(16*baud) - 1;

Still, I'd personally prefer the previous version since it makes it
explicit.  C type promotion rules are often not easy to understand at
a first glance.

-- 
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]