boolean function problem.

From: JasBascom (jasbascom_at_aol.com)
Date: 01/20/04


Date: 20 Jan 2004 07:50:33 GMT

The function i'm having trouble with is of type boolean, the problem is, is
that it is evaluating everything to true, and nothing to false.
later the function will be used thus: if(!checkdigitforpartnum
(rec.Newcrecord.Customercode)){
prnfile<< "Invalid" <<endl
prnfile<< record << endl;
}
 Here is what the function is suppose to do. Rec is the object of a union, and
Newcrecord is the object of a struct.
I107400118090003
This should be a false record, because the part number is invalid (011809) the
last digit should be an 'X'
0 1 1 8 0
* * * * *
6 5 4 3 2
_______

product = 0 + 5 + 4 + 24 + 0 = 33

result -= (product - 11);

check_11 (last digit in the part number) = 11

string[5] should be 'X', not 9 as stated. Can anyone tell me how i might be
able to write this function as an int etc, or tell me what is wrong with my own
function.

bool checkdigitforpartnum( char* string )
{
int partnumcheck =0;
int product;
int result =0;
int w1, w2, w3, w4, w5;

        w1 = (string[0] - '0') * 6;
        w2 = (string[1] - '0') * 5;
        w3 = (string[2] - '0') * 4;
        w4 = (string[3] - '0') * 3;
        w5 = (string[4] - '0') * 2;
        string[5];

product = (w1 + w2 + w3 + w4 + w5) % 11;

result -= (product - 11);

partnumcheck = (11 - result);

if(partnumcheck = 11)
{
        if(string[5] == 'x' || string[5] == 'X')
                return true;
}
else
if(partnumcheck = 11)
{
        if(string[5] != 'x' || string[5] != 'X')
        return false;
}
else
if(string[5] != partnumcheck)
{
        return false;
}
else
if(string[5] == partnumcheck)
{
        return true;
}

what follows is my coursework explanation of how to achieve the desire result.
the rec.Newcrecord.customercode is a char array.

        Cust Code 2 4 6 8
              x
        Weight 5 4 3 2
- - - - - - - - - - - - - - - - - - - - - - - - - - -
                        10 16 18 16

The code to accomplish this could be something like the following, this step
should be converted so that it uses a loop and avoids repetition, and the best
way to do this is to store the weights in an array:

        W1 = (custno[0] - ‘0’) * 5;
        W2 = (custno[1] - ‘0’) * 4;
        W3 = (custno[2] - ‘0’) * 3;
        W4 = (custno[3] - ‘0’) * 2;

The next step is to add up all of these values. In the example above this would
be 10 + 16 + 18 + 16. Which will give us a result of 60. We need to subtract
zero from the custno[0] so we get the decimal value of the element. By
subtracting the ASCII value of ‘0’ from the ASCII value of ‘2’ gives us
the decimal 2.

Next we need to get the remainder of dividing 60 by 11. To do this we use the
mod operator. This will give us a number between 0 and 10 inclusively.

        result = (w1 + w2 + w3 + w4) % 11;

The result is then subtracted from 11. This will give us a number between 1
and 11 inclusive. In our example 11-5=6 therefore the check digit is 6. If
result2 is 10 the check digit needs to be a 0 and if result2 is 11 then the
check digit needs to be an X. Look at the following grid:

result2 check digit
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 0
11 X

The last element in the customer code array must be checked against the results
of the previous calculations. The customer code is only valid if the last digit
matches the check digit in the grid above that corresponds to result2.

NOTE: The appropriate use of loops would make this code more efficient.

Here are some examples of using the modulus 11 to test the check digit :-

The formats laid down for modulus 11 checks are as follows
Example 1:
Full customer number example: 24686

Waiting number: 5432

Store the last character ‘6’

Get first number 2

Multiply it by the first weighted number
        2 * 5 = 10

Get next number 4

Multiply it by the next weighted number
        4* 4 = 16

Get next number 6

Multiply it by the next weighted number
        6* 3 = 18

Get last number 8

Multiply it by the first weighted number
        8* 2 = 16

Add all numbers together
        10 + 16 + 18 + 16 = 60

Modulus the total by the specified 11
({60 - 11 = 49}
                                                                                  {49 - 11 = 38}
                                                {38 - 11 = 27}
                                                {27 - 11 = 16}
          16 - 11 = 5

                                        result is 5.

Subtract the result (5) from the modulus (11)

                                                11 - 5 = 6

is the end result (the 6) the same as the fifth character in the customer code.

If the result 6 is equal to the last character (‘6’ - ‘0’ = 6)



Relevant Pages

  • Re: Summation, modulo and decimal
    ... >I'm trying to use the modulo (modulus, mod, %) to do the following: ... >The problem is that modulo is only def. ... It not worked because before it shift the ... >digit to the left the number is added to the previous value, so, I used ...
    (sci.math)
  • Re: convert dec number to HEX and oct and bin without c library function
    ... conversions. ... To convert from decimal to an integer, take the first digit, and convert ... need to take modulus ten for the last digit, divide by ten, take modulus ten ...
    (comp.lang.c)
  • reversing a modulus operation
    ... four digit number e.g 1234 has been separated into it's individual digits ... I have to write a routine to reverse the operation of addition of 7 & ... modulus 10 so that the original number is known. ... only be 0 - 9 as the original input is limited to a four digit integer) ...
    (alt.comp.lang.learn.c-cpp)
  • Re: reversing a modulus operation
    ... youKnowme wrote: ... For each digit I have had to calculate the modulus of 10 for each ... int encrypt_single_digit ...
    (alt.comp.lang.learn.c-cpp)