Posts: 2,765
Threads: 138
Joined: Nov 2002
Code: FUNCTION validate% (userinput$, decmax%)
validate% = -1
FOR i = 1 TO LEN(userinput$)
IF MID$(userinput$, i, 1) = "." THEN
dec% = dec% + 1
ELSE
IF dec% = 1 THEN decamount% = decamount% + 1
IF ASC(MID$(userinput$, i, 1)) > 57 OR ASC(MID$(userinput$, i, 1)) < 48 THEN validate% = 0: EXIT FUNCTION
END IF
IF decamount% > decmax% THEN validate% = 0: EXIT FUNCTION
IF dec% > 1 THEN validate% = 0: EXIT FUNCTION
NEXT i
END FUNCTION
Quote:WHITETIGER,
Works pretty good, except:
* allows leading and trailing spaces.
* allows multiple decimal pointss, like 12.34.56
* when zero decimals are specified, it allows one trailing decimal point.
*****
1. does not
2. not anymore
3. huh?
Back by popular demand!
I will byte and nibble you bit by bit until nothing remains but crumbs.
Posts: 1,956
Threads: 65
Joined: Jun 2003
HEY GUYS... SORRY, GOT TO GO NOW... CATCH YOU LATER.
*****
Posts: 3,368
Threads: 195
Joined: Jan 2003
ok, good contest. =)
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."
Visit www.neobasic.net to see rubbish in all its finest.
Posts: 1,956
Threads: 65
Joined: Jun 2003
TO ALL:
It turns out I was wrong about leading and trailing spaces. The INPUT statement suppresses these spaces, so your functions will never see them.
I again took the lastest posted code of each of you and complied and tested them for the following results:
TO WHITETIGER: You still have the following anomalies:
1) Null is still allowed.
2) When zero decimal places are specified, you allow a trailing decimal point, like 123.
3) Regardless of how many decimal places are specified (0 or above), you allow an input field containing only a decimal point.
TO NATHAN:
When the decimal places specified are greater than zero, you allow an input field containing only a decimal point.
TO AGAMEMNUS:
When the decimal places specified are greater than zero, you allow an input field containing only a decimal point.
SUMMARY:
In my opinion you all have too many IF's in your logic.
WhiteTiger has 5
Nathan has 7
Agamemnus has 7, but could be considered as 6.
SUGGESTION: When a piece of code is not working 100%, you shouldn't try to fix it by adding a couple of more IF's, you should re-think it and code it again.
i have a piece of code which I'll post when we're all done. It has a total of 4 IF's: 1 for the null, 2 for the decimal point logic, and 1 for the validation from 0 to 9.
*****
Posts: 3,368
Threads: 195
Joined: Jan 2003
hmmmm. You didn't specify that. Actually, you specified something very interesting:
Quote: But may contain a decimal point. The number of decimal points that the number can contain is a specification for the input field.
:lol:
Anyways,
even if you do specify that, you need more than 4 IFs:
one for the length test. (you can't get out of it)
two for a 1-9 test (you really can't get out of that either)
one to check if the decimal exists.
one to check if the decimal position is zero after checking if the decimal exists.
one to check whether the decimal is at the very end after checking if the decimal exists.
one to check whether there are too many digits to the right of the decimal after checking whether the decimal exists.
So that's 7.
Here is a revised one that is a little faster and uses fewer IFs, de facto (?):
Code: FUNCTION is.decimal% (userinput$, decimal.position%)
s.len% = LEN(userinput$)
IF s.len% = 0 THEN EXIT FUNCTION
FOR i% = 1 TO s.len%
temp$ = MID$(userinput$, i%, 1)
IF temp$ = "." THEN
IF decimal.position% = 0 THEN EXIT FUNCTION
IF decimal.position% - s.len% + i% < 0 THEN EXIT FUNCTION
IF i% = s.len% THEN EXIT FUNCTION
DO: i% = i% + 1
temp$ = MID$(userinput$, i%, 1)
n% = ASC(temp$)
IF n% > 57 THEN EXIT FUNCTION
IF n% < 48 THEN EXIT FUNCTION
IF i% = s.len% THEN EXIT DO
LOOP
is.decimal% = -1
EXIT FUNCTION
ELSE
n% = ASC(temp$)
IF n% > 57 THEN EXIT FUNCTION
IF n% < 48 THEN EXIT FUNCTION
END IF
NEXT i%
is.decimal% = -1
END FUNCTION
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."
Visit www.neobasic.net to see rubbish in all its finest.
Posts: 1,956
Threads: 65
Joined: Jun 2003
AGAMEMNUS:
The number of DECIMAL POINTS is determined or specified by the program. This value is passed to the function as the second parameter. The function should work correctly whether zero or greater value is specified.
Your new version now has 9 IF's. Much too many. You now need a map to follow the code. Here's the results:
1) Got a compile error. You had two FOR's, one within the other, both using FOR I%. I changed the second one (and it's references) to FOR I2%. Now it compiled and ran.
2) For some strange reason, when decimal points is 2, it accepts a value of .12, but rejects .1 only. I suspect a problem with the nested FOR which I "fixed".
3) The rest looks ok.
*****
Posts: 3,368
Threads: 195
Joined: Jan 2003
What I meant about decimal points is that in English it's decimal places, not decimal points. Number of decimal points means number of periods.
About the other thing, I made a booboo with that condition with an ending decimal point. It should be "if i% = s.len%"
Fixing it, and the stupid compiler error which shouldn't happen, now. (Updated)
Anyways, in otherwise optimized code, one can increase efficiency by avoiding testing for a condition that has already been proved true or false. In this case, I removed code for checking extra periods in favor of just testing whether everything after that period is a number. It's faster that way. You can try to prove me wrong by coding it both ways and comparing.
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."
Visit www.neobasic.net to see rubbish in all its finest.
Posts: 1,956
Threads: 65
Joined: Jun 2003
AGAMEMNUS,
You're right. I should refer to number of decimal places not decimal points.
Ok, I'll wait for your next updated version.
*****
Posts: 115
Threads: 6
Joined: Feb 2003
is this right? this 1 is a lil longer then the others since i return error strings when a error is found...
Code: DEFINT A-Z
DECLARE FUNCTION Validate% (S$, MaxDecimals%)
DIM SHARED Validate.Error AS STRING
CLS
CONST Number = "3.14.15323"
CONST MaxDecimals = 2
LOCATE 2, 2: PRINT "Validate Results-> "; Validate(Number, MaxDecimals)
LOCATE 1, 2: PRINT "Error Results-- "; Validate.Error
LOCATE 3, 2: PRINT "String Validated-> "; Number
FUNCTION Validate (S$, MaxDecimals)
IF LEN(S$) = 0 THEN
Validate.Error = "Is invalid, String is null."
Validate = 0
EXIT FUNCTION
END IF
IF ASC(RIGHT$(S$, 1)) = 46 THEN
Validate.Error = "Is invalid, Cannot end with decimal point."
Validate = 0
EXIT FUNCTION
END IF
IF ASC(LEFT$(S$, 1)) = 46 THEN
Validate.Error = "Is invalid, Cannot start with decimal point."
Validate = 0
EXIT FUNCTION
END IF
FOR I = 1 TO LEN(S$)
SELECT CASE ASC(MID$(S$, I, 1))
CASE 48 TO 57 ' 0 to 9
' Just do nothing...
CASE 46 ' Decimal point
DecimalsFound = DecimalsFound + 1
IF DecimalsFound > MaxDecimals THEN
Validate.Error = "Is invalid, To many decimal points."
Validate = 0
EXIT FUNCTION
END IF
CASE ELSE ' Everything else
Validate.Error = "Is invalid, Must be numeric."
Validate = 0
EXIT FUNCTION
END SELECT
NEXT
Validate = -1
Validate.Error = "No Errors Reported."
END FUNCTION
very F***ing song remains the same
To everyone who sucks-up for the fame
Out of strength you know we speak the truth
Every trend that dies is living proof
MasterMinds Software
Posts: 1,956
Threads: 65
Joined: Jun 2003
Congratulations, BinarySHOCK, on a very clean, structured and complete piece of code. This is an example of code that you would want to put into production. It doesn't just say that the input is invalid, it tells the user why!
I can't check it right now, I don't have access to my compiler. But, it looks good. I did notice however that you don't allow a leading decimal point. This should be allowed when maxdecimals is greater than zero. Example: when maxdecimals is 2, then .75 would be valid.
*****
|