comp.lang.ada
 help / color / mirror / Atom feed
From: "Adam Beneschan" <adam@irvine.com>
Subject: Re: Char type verification
Date: 15 Nov 2006 15:36:23 -0800
Date: 2006-11-15T15:36:23-08:00	[thread overview]
Message-ID: <1163633783.126843.241410@i42g2000cwa.googlegroups.com> (raw)
In-Reply-To: 1163628033.606530.190550@i42g2000cwa.googlegroups.com

KE wrote:
> Hi
>
> Assume that I have the following C code:
>
> #include <stdio.h>
>
> #define uchar   unsigned char
>
>
> static uchar UCASE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
>
> int _isupper(uchar c)
> {
>    return (c==UCASE[(c%'A')%26]);
> }
>
> int main(int argc, char *argv[])
> {
>     uchar c = (uchar) *argv[1];
>     printf("_isupper('%c')? = %d\n",c,_isupper(c));
>
>     return 0;
> }
>
> (I don't claim this is terribly safe, localizable, transparent, etc.
> It's just practical within the confines of ASCII, and efficient since
> it uses a table-lookup technique.)

Uhhhmmm.  It sounds like you've heard somewhere that doing a table
lookup always makes things efficient.  Sorry, no.  There are cases
where table lookups are superior to other ways of doing things.  This
is not one of them.  If you really wanted a table lookup here, it would
have been far better to set up an array indexed by all 256 characters
whose values were 1 or 0 (1 for the upper-case letters and 0 for the
rest), and just loaded the result from that array.  Even then, that
would be at best only marginally more efficient than c>='A' && c<='Z',
and probably less efficient on many processors.  The way you've coded
it is certainly less efficient, plus it's really hard to figure out
what it does.  I had to stare at it for a minute to convince myself it
was correct.

> Now, how would you convert this to Ada. As you can imagine, Ada
> complains loudly with my fast and loose conversions of data types (char
> to uchar, that to int, etc.)
>
> (This is not some class assignment or anything. I'm a 40-something
> coder new to Ada, and I'd like to see in how many different ways you
> gentlemen will attempt to solve this.)
>
> NB: The question's intent is, what would be the safest *and* the most
> transparent way to marshall the details of this in Ada-95?

The first bit of rethinking you need to do: In C, a character is just a
kind of integer; "signed char" is an integer that's normally in the
range -128..127, and "unsigned char" is an integer in the range 0..255,
and "char" can be either one if I recall correctly.  Also, 'A' is an
integer that means exactly the same thing as 65.

In Ada, the standard Character type is not an integer type; it's an
"enumeration" type.  The possible values of an object of an enumeration
type come from a list---in this case, a list of characters---but the
values are not integers.  To convert to and from integers, use the 'Pos
and 'Val attributes.  If C is a Character and N is an Integer,
   N := Character'Pos(C);
   C := Character'Val(N);
will do the conversions you want.

Georg pointed out a couple ways to implement "isupper".  I've already
mentioned that your implementation seems poor.  But assuming you wanted
to implement it in Ada exactly the same way as you did above, try
something like:

   function IsUpper (C : Character) return Boolean is
      UCASE : constant String := "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   begin
      return C = UCASE (UCASE'First + (Character'Pos(C) mod
Character'Pos('A')) mod 26);
   end IsUpper;

Note that arrays do not automatically begin at offset 0 (and String
types cannot begin at offset 0), which is why UCASE'First is added to
the index.

Note also that this function returns a Boolean, not an
Integer---Boolean is another enumeration type with values (FALSE,
TRUE).  To output this, you can use Boolean'Image(IsUpper(C)), which
outputs either FALSE or TRUE which is a lot nicer than 1 or 0 in my
opinion.

This isn't a complete translation of your program---I haven't gone into
how to get at the command-line arguments---but hopefully it will get
you started.

                     -- Adam




  parent reply	other threads:[~2006-11-15 23:36 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-11-15 22:00 Char type verification KE
2006-11-15 21:57 ` Georg Bauhaus
2006-11-15 23:15   ` KE
2006-11-16  4:48     ` Jeffrey R. Carter
2006-11-16 19:53       ` Adam Beneschan
2006-11-16 23:30       ` Yves Bailly
2006-11-17  0:48         ` Jeffrey R. Carter
2006-11-17  1:59           ` Adam Beneschan
2006-11-17 11:30           ` Stephen Leake
2006-11-17 15:33             ` KE
2006-11-17 15:10               ` Georg Bauhaus
2006-11-17 18:30               ` Ludovic Brenta
2006-11-18  2:29                 ` Brian May
2006-11-17 19:45               ` Jeffrey R. Carter
     [not found]               ` <mQm7h.8782$ig4.3262@newsread2.news.pas.earthlink.net>
2006-11-17 19:56                 ` Jeffrey R. Carter
     [not found]                   ` <omz7h.222$1s6.165@newsread2.news.pas.earthlink.net>
2006-11-19  2:19                     ` OT: French Idioms (was Re: Char type verification) Jeffrey R. Carter
2006-11-19  9:04                       ` Dmitry A. Kazakov
2006-11-17 21:22         ` Char type verification Simon Wright
2006-11-17 23:59           ` Yves Bailly
2006-11-15 23:23 ` Simon Wright
2006-11-15 23:33   ` KE
2006-11-16  4:52     ` Jeffrey R. Carter
2006-11-15 23:36 ` Adam Beneschan [this message]
2006-11-15 23:55   ` KE
2006-11-16  4:54     ` Jeffrey R. Carter
2006-11-16  1:08 ` jimmaureenrogers
2006-11-16  1:45   ` KE
2006-11-16  2:15     ` jimmaureenrogers
2006-11-16  2:42     ` Steve Whalen
2006-11-16  9:36     ` Alex R. Mosteo
2006-11-16  7:02 ` KE
2006-11-16 17:04   ` Dmitry A. Kazakov
2006-11-16 22:43   ` Brian May
  -- strict thread matches above, loose matches on Subject: below --
2006-11-16 16:01 Anh Vo
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox