2^0 constant avr-gcc bug ?

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I have stumbled across a minor bug in avr-gcc. I tried to set a constant equal to [ 2^0 ], which, in my math book, should come out as the value 1. It doesn't. I haven't been able to determine exactly what value is produced since I can't simply "print" at the moment.

Summary:
const int led = 1 ; // Result is [ 1 ] as expected.
const int led = 2^0 ; // Result is not [ 1 ] !

Compiler version:
> avr-gcc -dumpversion
4.3.2
on Win XP SP3

Command-line:
avr-gcc -g -Wall -Wno-unused-variable -Os -mmcu=atmega16 -DF_CPU=1000000UL -c -o LEDBTN.o LEDBTN.c

Attached is the source file.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

2 XOR 0 is two in my book :). Remember, in the C language, the "^" operator is an XOR and not an exponential like in common maths.

To get what you're after, you'll have to use the functions provided in the AVR math library.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
To get what you're after, you'll have to use the functions provided in the AVR math library.

I wouldn't, it would be a terrible waste. 2 to the power of x would be (1 << x).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:
2 XOR 0 is two in my book :). Remember, in the C language, the "^" operator is an XOR and not an exponential like in common maths.
Until today, the only places I'd seen "^" used for
exponentiation was in e-mails and plain text articles.
In such places, I used "**" even when responding to uses of "^".

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I definitely must have had a brain fart at the time...
I mistook the XOR operator for a power operator.
"m ^ n" is really "m XOR n", not at all what I wanted.

"There is no inline operator to do the power [math operation] (e.g. 5 ^ 2 is not 25, and 5 ** 2 is an error), but there is a power function."

Since I want to use a compiler directive, using a function call is not even possible. Using "m << n" is obviously the only reasonable way to go, but the syntax is cryptic. Using a macro makes usage and readability much better. How about:

#define TwoToThe(n) (1 << n)

This gets the bit position for, say, reading/writing a port bit, which was my initial goal.

Here's a re-work of Dean's original bit/bits manipulation macros. I think they are much more understandable:

#define aBit(x) (1 << (m))
#define aLongBit(x) ((unsigned long) 0x00000001 << (m))
;
#define BitsGet(p,m) ((p) & (m))
#define BitsSet(p,m) ((p) |= (m))
#define BitsClear(p,m) ((p) &= ~(m))
#define BitsToggle(p,m) ((p) ^= (m))
#define BitsWrite(c,p,m) (c ? BitsSet(p, m) : BitsClear(p, m))

These make port bit operations both trivially easy and readily understandable. Note that I've renamed all "BitX" macros to "BitsX". It's *extremely important* to know that these macros operate on *any* combination of bits, *not* just a single bit. This crucial explanation was inadvertently left out of Dean's post.

No one in their right mind wants to mess around with operator combinations like " &= ~(m) " !!! This reminds me of the long-dead APL programming language which justly deserved its cruel death due to its grossly cryptic unreadability. (You have to see some of its actual coding to believe your eyes. [url]http://en.wikipedia.org/wiki/APL_(programming_language)#Examples[/url])

Here;s some usage of the macros:

void LedToggle( void ) {
BitsToggle( PORTB, aBit(ledBit) ) ; // Read in the current output state
} // and write back the inverted value.

void LedON( void ) {
BitsSet( PORTB, aBit(ledBit) ) ; // turn led On=1 (sources LED current)
}

void LedOFF( void ) {
BitsClear (PORTB, aBit(ledBit) ) ; // turn led Off=0 (won't source LED current)
}

// -------------------------------------------

#define btnBit 4 // PB-4

#define ledBit 0 // PB-0

// -------------------------------------------

...

// Read the switch's current input level.
inState = BitsGet( PORTB, aBit(btnBit) ) ;

_delay_ms ( 200 ) ; // Heuristic debounce delay.

if ( BitsGet(PORTB, aBit(btnBit)) == inState ) {
LedToggle() ; // HW method for toggling the LED port bit state.
}

[/img]

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> Until today, the only places I'd seen "^" used for
> exponentiation was in e-mails and plain text articles.

It most likely originates from BASIC.

> In such places, I used "**" even when responding to uses of "^".

Which replaces it by the FORTRAN syntax. ;-)

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have no problem with PORTB&=~(1<<PB4) or PORTB|=(1<<PB4). It's a lot less typing :) You instantly recognize these constructs after a while, they become part of your visual memory so to say.

I rather prefer to #define a macro to encapsulate an entity like a LED or button, then just obfuscate the low level bit operations in non-standard macros.

#define KILLSWITCH_PORT PORTB
#define KILLSWITCH_BIT  PB4
#define ReadKillSwitch  ~(KILLSWITCH_PORT & (1<<KILLSWITCH_BIT)) // Active low

If you like a verbose syntax try VHDL :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pascor, you may need to hit the tutorial section on clearing flags, reading pins (looking at your attached file).

If you want some 'friendly' macros, you can look at-
http://www.mtcnet.net/~henryvm/b...
which will make 'multiple bits' easier (or I should say, 'easier'). Sometimes 'easier' can actually be harder, though.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

> Until today, the only places I'd seen "^" used for
> exponentiation was in e-mails and plain text articles.

It most likely originates from BASIC.

IIRC "**" was used in BASIC back in the 70s
(UNIVAC BASIC on a UNIVAC 1108 and later a 1100/80, both running OS-1100 and CTS, for those active in them ancient days).

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

It most likely originates from BASIC.

http://en.wikipedia.org/wiki/Exp...
Quote:
In programming languages

The superscript notation xy is convenient in handwriting but inconvenient for typewriters and computer terminals that align the baselines of all characters on each line. Many programming languages have alternate ways of expressing exponentiation that do not use superscripts:

* x ↑ y: Algol, Commodore BASIC
* x ^ y: BASIC, J, MATLAB, R, Microsoft Excel, TeX (and its derivatives), Haskell (for nonnegative integer exponents), and most computer algebra systems
* x ^^ y (for fractional base, integer exponents): Haskell
* x ** y: Ada, Bash, COBOL, Fortran, FoxPro, Gnuplot, OCaml, Perl, PL/I, Python, Rexx, Ruby, SAS, ABAP, Haskell (for floating-point exponents), Turing, VHDL
* x⋆y: APL
* Power(x, y): Microsoft Excel, Delphi/Pascal (declared in "Math"-unit)
* pow(x, y): C, C++, PHP
* Math.pow(x, y): Java, JavaScript, Modula-3, Standard ML
* Math.Pow(x, y): C#
* (expt x y): Common Lisp, Scheme
* math:pow(x, y): Erlang

In Bash, C, C++, C#, Java, JavaScript, Perl, PHP, Python and Ruby, the symbol ^ represents bitwise XOR. In Pascal, it represents indirection. In OCaml and Standard ML, it represents string concatenation.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.