comp.lang.ada
 help / color / mirror / Atom feed
* New to Ada, noticing something strange.
@ 2005-09-29 17:20 mike.martelli
  2005-09-29 18:39 ` Jeffrey R. Carter
  0 siblings, 1 reply; 11+ messages in thread
From: mike.martelli @ 2005-09-29 17:20 UTC (permalink / raw)


Here is an excerpt of my code.  Every function works as it should, the
program is set up correct, and the correct values are being passed to
all functions.

The idea of the program is perform arithmetic on arbitrarily long
integers that are inputted as strings using the paper and pencil
approach (digit by digit, from right from right to left, with a carry
digit).  The user will enter a base, operand1, and operan2 via command
line arguments.  (if you need more explanation let me know).

with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Command_Line;
with Ada.Strings.Unbounded;
with Ada.Characters.Handling;

use Ada.Text_IO;
use Ada.Integer_Text_IO;
use Ada.Command_Line;
use Ada.Strings.Unbounded;

procedure BigInts is
...

charMap: array (Character) of Integer;

charMap('0') := 0;
charMap('1') := 1;
charMap('2') := 2;
...
charMap('E') := 14;
charMap('F') := 15;

 function C2C(strChar: String) return Character is
 begin
    Put_Line(strChar);
    case Integer'Value(strChar) is
	when 10 => return 'A';
	when 11 => return 'B';
	when 12 => return 'C';
	when 13 => return 'D';
	when 14 => return 'E';
	when 15 => return 'F';
	when others => return strChar(1);
    end case;
 end C2C;

 function AddDigits(op1, op2: Character) return Character is
 begin
    charDigit:=C2C(Integer'Image(charMap(op1)+charMap(op2)+carry));

    Put("Print1: ");
    Put(C2C(Integer'Image(charMap(op1)+charMap(op2)+carry)));

    if(charMap(op1)+charMap(op2)+carry)>(charMap(charBase)-1) then
        Put_Line("here1: ");

        --Set the digit to the highest possible values
	charDigit:=C2C(Integer'Image(charMap(charBase)-1));

        --carry is all of the rest
	carry:=(charMap(op1)+charMap(op2)+carry)-(charMap(charBase)-1);
    else
	Put_Line("here2: ");
	carry:=0; --there is no carry
    end if;

    Put("Digit: ");
    Put(charDigit);
    New_Line;
    Put("Carry: ");
    Put(carry);
    New_Line;
    return charDigit;
 end AddDigits;
...
end BigInts;

(I removed some extra white space so it would align better in the post)

I have some Put()/Put_Line() statements in AddDigits() for debugging
purposes.  The problem is in Convert2Character(), nothing was ever
being returned by that function.  I added the Put_Line(strChar) to make
sure a correct value was being passed to it.  Once I added that
Put_Line() a value was being returned by the function and it was
correct.  It seems that a Put_Line() is needed for some reason or it
does not do what it is supposed to do.




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 17:20 New to Ada, noticing something strange mike.martelli
@ 2005-09-29 18:39 ` Jeffrey R. Carter
  2005-09-29 19:05   ` mike.martelli
  0 siblings, 1 reply; 11+ messages in thread
From: Jeffrey R. Carter @ 2005-09-29 18:39 UTC (permalink / raw)


mike.martelli@gmail.com wrote:

> (I removed some extra white space so it would align better in the post)

You removed more than that.

> I have some Put()/Put_Line() statements in AddDigits() for debugging
> purposes.  The problem is in Convert2Character(), nothing was ever
> being returned by that function.  I added the Put_Line(strChar) to make
> sure a correct value was being passed to it.  Once I added that
> Put_Line() a value was being returned by the function and it was
> correct.  It seems that a Put_Line() is needed for some reason or it
> does not do what it is supposed to do.

You don't have anything named Convert2character, nor do you have Chardigit or 
Carry declared anywhere, and you index a String by 1 without any reason to 
expect that 1 is in its range, so it's hard to tell what might be happening. I'm 
also not sure what you mean by nothing being returned; do you mean execution 
entered the function and stopped? An exception is raised?

In any case, if the only change you made was to add a Put_Line, then it appears 
you have a compiler bug. You didn't mention what compiler you're using, but you 
might want to inform your compiler vendor.

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 18:39 ` Jeffrey R. Carter
@ 2005-09-29 19:05   ` mike.martelli
  2005-09-29 22:25     ` Randy Brukardt
  2005-09-30  6:23     ` Jeffrey R. Carter
  0 siblings, 2 replies; 11+ messages in thread
From: mike.martelli @ 2005-09-29 19:05 UTC (permalink / raw)


Sorry, well I only gave the relvent portion of the code and I meant I
took the whitespace out of this part so it is very compressed but I
wanted it to be easy to read in the post.  I also changed the name of
the function from Convert2Character to C2C to save space.  All of the
other variables are declared and there, I just didnt include them.  You
can assume all variables are assigned and exist.  As for indexing the
string by 1, assume it is always of length 1 (i have a function that
make sure of it) - i know i can use a chracter but I left it like this
for now.

I am using the GNAT compilier, I do not know what version.  It is on my
schools server (NYU).




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 19:05   ` mike.martelli
@ 2005-09-29 22:25     ` Randy Brukardt
  2005-09-29 23:58       ` mike.martelli
  2005-09-30  6:23     ` Jeffrey R. Carter
  1 sibling, 1 reply; 11+ messages in thread
From: Randy Brukardt @ 2005-09-29 22:25 UTC (permalink / raw)


<mike.martelli@gmail.com> wrote in message
news:1128020747.226853.325750@z14g2000cwz.googlegroups.com...
> Sorry, well I only gave the relvent portion of the code and I meant I
> took the whitespace out of this part so it is very compressed but I
> wanted it to be easy to read in the post.

You'll probably get more help if you posted an entire compilable example. My
experience supporting customers of our Ada compiler is that partial examples
rarely are of much use (unless the error is glaringly obvious). Often, users
will remove something "irrelevant" which is actually the cause of the
problem (be it a compiler bug or a user error...).

                         Randy.






^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 22:25     ` Randy Brukardt
@ 2005-09-29 23:58       ` mike.martelli
  2005-09-30  0:28         ` mike.martelli
                           ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: mike.martelli @ 2005-09-29 23:58 UTC (permalink / raw)


Ok, Randy sounds good here is my code.  I also tried compiling in on
Laptop with the latest GNAT compilier and I get the same results.

==================================================

with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Command_Line;
with Ada.Strings.Unbounded;
with Ada.Characters.Handling;

use Ada.Text_IO;
use Ada.Integer_Text_IO;
use Ada.Command_Line;
use Ada.Strings.Unbounded;

	procedure BigInts is
		base, operand1, operand2: Unbounded_String :=
To_Unbounded_String("");
		charMap: array (Character) of Integer;
		NumOfArgs, size, carry: Integer := 0;
		charBase, digit, charDigit: Character;

		procedure PopulateArray is
		begin
			charMap('0') := 0;
			charMap('1') := 1;
			charMap('2') := 2;
			charMap('3') := 3;
			charMap('4') := 4;
			charMap('5') := 5;
			charMap('6') := 6;
			charMap('7') := 7;
			charMap('8') := 8;
			charMap('9') := 9;
			charMap('A') := 10;
			charMap('B') := 11;
			charMap('C') := 12;
			charMap('D') := 13;
			charMap('E') := 14;
			charMap('F') := 15;
		end PopulateArray;

		function ResultSize(operand1, operand2: Unbounded_String) return
Integer is
		begin
			if Length(operand1) > Length(operand2)  then
				size := Length(operand1);
			else
				size := Length(operand2);
			end if;

			return size;
		end ResultSize;

		function Convert2Character(strChar: String) return Character is
		begin
		--Put_Line(strChar);
			case Integer'Value(strChar) is
				when 10 => return 'A';
				when 11 => return 'B';
				when 12 => return 'C';
				when 13 => return 'D';
				when 14 => return 'E';
				when 15 => return 'F';
				when others => return strChar(1);
			end case;
		end Convert2Character;

		function AddDigits(charOp1, charOp2: Character) return Character is
		begin
			charDigit := Convert2Character(Integer'Image(charMap(charOp1) +
charMap(charOp2) + carry));
			Put("Print1: ");
			Put(Convert2Character(Integer'Image(charMap(charOp1) +
charMap(charOp2) + carry)));
			if (charMap(charOp1) + charMap(charOp2) + carry) >
(charMap(charBase) - 1) then
				Put_Line("here1: ");
				charDigit := Convert2Character(Integer'Image(charMap(charBase) -
1)); --Set the digit to the highest possible values
				carry := (charMap(charOp1) + charMap(charOp2) + carry) -
(charMap(charBase) - 1); --carry is all of the rest
			else
				Put_Line("here2: ");
				carry := 0; --there is no carry
			end if;
			Put("Digit: ");
			Put(charDigit);
			New_Line;
			Put("Carry: ");
			Put(carry);
			New_Line;
			return charDigit;
		end AddDigits;

	begin
		NumOfArgs := ARGUMENT_COUNT;

		if NumOfArgs = 3 then
			base := To_Unbounded_String(Argument(1));
			operand1 := To_Unbounded_String(Argument(2));
			operand2 := To_Unbounded_String(Argument(3));

			if not (Integer'Value(To_String(base)) > 1) or not
(Integer'Value(To_String(base)) < 16) then
					Put("The base entered is not valid.");
					return;
			end if;

			charBase := Convert2Character(To_String(base));

			--converts all lowercase characters to uppercase
			for i in 1 .. Length(operand1) loop
				case Element(operand1, i) is
					when 'a' => Replace_Element(operand1, i, 'A');
					when 'b' => Replace_Element(operand1, i, 'B');
					when 'c' => Replace_Element(operand1, i, 'C');
					when 'd' => Replace_Element(operand1, i, 'D');
					when 'e' => Replace_Element(operand1, i, 'E');
					when 'f' => Replace_Element(operand1, i, 'F');
					when others => Replace_Element(operand1, i, Element(operand1, i));
				end case;
			end loop;

			--converts all lowercase characters to uppercase
			for i in 1 .. Length(operand2) loop
				case Element(operand2, i) is
					when 'a' => Replace_Element(operand2, i, 'A');
					when 'b' => Replace_Element(operand2, i, 'B');
					when 'c' => Replace_Element(operand2, i, 'C');
					when 'd' => Replace_Element(operand2, i, 'D');
					when 'e' => Replace_Element(operand2, i, 'E');
					when 'f' => Replace_Element(operand2, i, 'F');
					when others => Replace_Element(operand2, i, Element(operand2, i));
				end case;
			end loop;

			PopulateArray;

			for i in 1 .. Length(operand1) loop
				if charMap(To_String(operand1)(i)) >= charMap(charBase) then
						Put_Line("Operand 1 is not valid with the base entered");
						return;
				end if;
			end loop;

			for i in 1 .. Length(operand2) loop
				if charMap(To_String(operand2)(i)) >= charMap(charBase) then
						Put_Line("Operand 2 is not valid with the base entered");
						return;
				end if;
			end loop;

			for i in reverse 1 .. ResultSize(operand1,operand2) loop
				digit := AddDigits(To_String(operand1)(i), To_String(operand2)(i));
				Put(digit);
				New_Line;
			end loop;
			--Print final carry digit
			Put("Final Carry: ");
			Put(carry);
			New_Line;
		else
			Put("Not enough args");
			return;
		end if;
	end BigInts;




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 23:58       ` mike.martelli
@ 2005-09-30  0:28         ` mike.martelli
  2005-09-30  6:06         ` Jeffrey R. Carter
                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: mike.martelli @ 2005-09-30  0:28 UTC (permalink / raw)


Also, I know I could use the To_Upper function in the
Ada.Characters.Handling package.  I wasn't using it at first for some
reason, but now am.




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 23:58       ` mike.martelli
  2005-09-30  0:28         ` mike.martelli
@ 2005-09-30  6:06         ` Jeffrey R. Carter
  2005-09-30  6:28         ` Jeffrey R. Carter
  2005-09-30 10:19         ` Georg Bauhaus
  3 siblings, 0 replies; 11+ messages in thread
From: Jeffrey R. Carter @ 2005-09-30  6:06 UTC (permalink / raw)


mike.martelli@gmail.com wrote:

> 		charMap: array (Character) of Integer;

You have undefined elements of this array, and may well be referencing them. You 
should probably initialize all of them:

type Char_Mapping is array (Character) of Integer;

Char_Map : Char_Mapping :=
('0' => 0, '1' => 1, '2' => 2, ... 'F' => 15, others => -16);

> 		NumOfArgs, size, carry: Integer := 0;

By making these Integer, you're implying that negative values are meaningful. 
These should probably be Natural. Size should probably be Positive.

> 				size := Length(operand1);

Why are you using a global variable here? Especially since it doesn't seem to be 
referenced anywhere else?

> 				when others => return strChar(1);

when others =>
    return Strchar (Strchar'First);

> 			--converts all lowercase characters to uppercase

Ada.Characters.Handling.To_Upper, as you noted elsewhere.

> 				if charMap(To_String(operand1)(i)) >= charMap(charBase) then

Here you can be referencing uninitialized values of Charmap, since the program 
has no control over the arguments it receives.

> 			for i in reverse 1 .. ResultSize(operand1,operand2) loop
> 				digit := AddDigits(To_String(operand1)(i), To_String(operand2)(i));

One of these strings may be shorter than the result of Resultsize, and when you 
try to index it with that value (first time through the loop), this should raise 
Constraint_Error.

So, what inputs did you run this with, and what output did you obtain?

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 19:05   ` mike.martelli
  2005-09-29 22:25     ` Randy Brukardt
@ 2005-09-30  6:23     ` Jeffrey R. Carter
  1 sibling, 0 replies; 11+ messages in thread
From: Jeffrey R. Carter @ 2005-09-30  6:23 UTC (permalink / raw)


mike.martelli@gmail.com wrote:

> As for indexing the
> string by 1, assume it is always of length 1 (i have a function that
> make sure of it) - i know i can use a chracter but I left it like this
> for now.

Note that a length of 1 and and index of 1 are 2 different things:

A : String (3 .. 3);

A'Length = 1, A'First = A'Last = 3; 1 is an invalid index for A

B : String (1 .. 9);

Put_Line (Item => B (4 .. 4) );

Passing a slice of length 1. Item'Length = 1, Item'First = Item'Last = 4; 1 is 
an invalid index.

> 		function AddDigits(charOp1, charOp2: Character) return Character is
> 		begin
> 			charDigit := Convert2Character(Integer'Image(charMap(charOp1) +
> charMap(charOp2) + carry));

If you call this with Charop1 => '9' and Charop2 => '9', your sum is 18. 
Integer'Image of that is " 18" (note the leading space), which is not of length 
1 (its lower index is 1, though). Convert2character should return ' '. I suspect 
you have a logic error here.

> I am using the GNAT compilier, I do not know what version.  It is on my
> schools server (NYU).

I see. When asking for help with homework, it's a good idea to make it clear 
that that's what you're doing. "gnatmake -v" should print the version; it also 
helps to know what platform you're running on. If you determine this is a 
compiler error, then you should probably report it to whoever administers the 
compiler on your system.

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 23:58       ` mike.martelli
  2005-09-30  0:28         ` mike.martelli
  2005-09-30  6:06         ` Jeffrey R. Carter
@ 2005-09-30  6:28         ` Jeffrey R. Carter
  2005-09-30 10:19         ` Georg Bauhaus
  3 siblings, 0 replies; 11+ messages in thread
From: Jeffrey R. Carter @ 2005-09-30  6:28 UTC (permalink / raw)


mike.martelli@gmail.com wrote:

> 			if not (Integer'Value(To_String(base)) > 1) or not
> (Integer'Value(To_String(base)) < 16) then

You might find "in" and "not in" (subtype membership operations) useful. The 
general form is

Value [not] in Subtype

"in" returns True if Value is a member of Subtype; "not in" if Value is not a 
member. This is defined for all types:

task type T (D : Integer);

subtype T1 is T (D => 1);

X : T (D => 7);

if X in T1 then -- True if X.D = 1

For a discrete type, the subtype may be given by a range:

if Integer'Value (To_String (Base) ) not in 1 .. 16 then

-- 
Jeff Carter
"There's no messiah here. There's a mess all right, but no messiah."
Monty Python's Life of Brian
84



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-29 23:58       ` mike.martelli
                           ` (2 preceding siblings ...)
  2005-09-30  6:28         ` Jeffrey R. Carter
@ 2005-09-30 10:19         ` Georg Bauhaus
  2005-09-30 16:43           ` mike.martelli
  3 siblings, 1 reply; 11+ messages in thread
From: Georg Bauhaus @ 2005-09-30 10:19 UTC (permalink / raw)


mike.martelli@gmail.com wrote:
> Ok, Randy sounds good here is my code.  I also tried compiling in on
> Laptop with the latest GNAT compilier and I get the same results.

And as Randy said, the issue is with code that didn't look suspicious.
IIUC.

> 		function Convert2Character(strChar: String) return Character is
...
> 			case Integer'Value(strChar) is
...
>				when others => return strChar(1);
...
> 			charDigit := Convert2Character(Integer'Image(charMap(charOp1) +
> charMap(charOp2) + carry));

Here, the 'Image has a space for non-negative value (or a minus sign for
negative values) in position 1.


-- Georg 



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: New to Ada, noticing something strange.
  2005-09-30 10:19         ` Georg Bauhaus
@ 2005-09-30 16:43           ` mike.martelli
  0 siblings, 0 replies; 11+ messages in thread
From: mike.martelli @ 2005-09-30 16:43 UTC (permalink / raw)


Well I want to thank you all for your help (sorry for not mentioning if
was for a school assignment).  It seems my problem was the padding that
would result from calling Interger'Image (thanks Georg).

The version of my program I posted was an older one (I have made
improvements on a different version that many of you mentioned but
didnt have that source with me).

The idea for the defining all elements in the array was a useful one
too (thanks Jeff) I was not sure how to do, becuase it would not let me
use 'others' in my procedure I had used to generate the array.  once i
generated it inline i was able to use the others keyword.

Thanks again.




^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2005-09-30 16:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-29 17:20 New to Ada, noticing something strange mike.martelli
2005-09-29 18:39 ` Jeffrey R. Carter
2005-09-29 19:05   ` mike.martelli
2005-09-29 22:25     ` Randy Brukardt
2005-09-29 23:58       ` mike.martelli
2005-09-30  0:28         ` mike.martelli
2005-09-30  6:06         ` Jeffrey R. Carter
2005-09-30  6:28         ` Jeffrey R. Carter
2005-09-30 10:19         ` Georg Bauhaus
2005-09-30 16:43           ` mike.martelli
2005-09-30  6:23     ` Jeffrey R. Carter

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