Confusion between strings and numbers

Hello friends,
I just ran into a strange situation.
I have a string: “v. 15. → Naniser”.
I want to extract the value 15 using a loop, since there might be multiple numbers.
The program interprets “Naniser” as NaN.
It works once I add IsNumeric.
Can you explain why?

“Nansier” is not a number but the framework parser looks for “NaN”, case insensitive at the start of the string, is my best guess. NaN does mean “Not a Number” after all, so more-or-less correct in this instance :grinning_face:. Do you expect to encounter “NaN”? If so then I’d do a direct case sensitive comparison for that case rather than converting.

Whether or not you know the format of the input string, you’re likely better off with RegEx, especially if this is an operation you need to perform frequently. Then you can handle multiple numeric string results within the same container string using a loop quite easily.

Untested code:

Var extractedNumbers() As String
Var rx As New RegEx
rx.SearchPattern = "\d+"

Var match As RegExMatch = rx.Search(inputString) // e.g. “v. 15. → Naniser”

While match <> Nil
  extractedNumbers.Add match.SubExpressionString(0) // "15"
  match = rx.Search()
End While

Just an addition: While ‘NaN’ means ‘Not a Number’ it is a technically valid value of a variable of type Double and you can assign it to such a variable. Mathematically it is an invalid value, like what you would get by calculating the square root of a negative number.

(Maybe I should get slapped on my wrist for this but I have sometimes used a sqrt(-1) value to indicate that the actual value isn’t currently known.)

Many thanks for the explanations and the code as well!
What I don’t understand is that my variable is declared as a string.
And thanks also for teaching me about RegEx.

Can you show us your code?

Dim NumS(-1) As String
if NumS(i) = "01." OR  NumS(i) = "02." OR ( Val(NumS(i)) >= 10 AND Val(NumS(i)) <= 210 ) Then
  Num_Conjug.Append( Val(NumS(i)) ) // On mémorise les nombres.
end if

As it stands this code snippet doesn’t make much sense. Where is the value of the variable i coming from? Did you forget to include a For loop?

You start out with an empty string array but in the second line you assume it somehow got filled – NumS(i) would raise an error if NumS was still empty.

That NumS is declared as an array of strings does make sense though.

In the age of AI, I hope my humble human intelligence at least had the sense to increment i.
The reason I’m asking is that, out of 69,000 records, I ran into this problem and only with naniser.
Of course, I didn’t include all the code.

That’s the problem … With just some random lines of code to go on I don’t understand what “What I don’t understand is that my variable is declared as a string” even means. (The obvious answer would be “Because you have declared it as such”.)

Take a chain “v. 15. → Naniser”
You split it in order to get Nums(i) and tell me what it happens with the word “Naniser”.

Hasn’t this been fully explained already? The string contains representations of numbers and for the purposes of Xojo the substring “15” is the representation of a number, but so is “NaN” (or “Nan” as the comparison is case insensitive) – it is the representation of the Double value you would get by evaluating sqrt(-1), for example. For a similar reason “inf” (infinity) and “-inf” (negative infinity) would be recognized as numbers.

Thus the recommendation to use RegEx and specify a pattern for the kind of numbers you want to be recognized, like strings of digits, possibly including a preceding minus sign and a decimal point. This way you define what counts as a number and what doesn’t.

If I understand correctly, I shouldn’t have asked my question the way I’d already solved it, but I was just intrigued.
But for me, ‘Naniser’ is neither sqrt(-Naniser), nor ∞(‘Naniser’), nor ∞(‘Naniser’).

Agree, somewhat surprising. I would have expected v to be 0, as it would be with any random string like “foobar”. Some careless coding deep in the bowels of Xojo.

Still untested code:

Var extractedNumbers() As Double
Var rx As New RegEx
rx.SearchPattern = "\d+"

Var match As RegExMatch = rx.Search(inputString) // e.g. “v. 15. → Naniser”

While match <> Nil
  extractedNumbers.Add match.SubExpressionString(0).ToDouble // "15"
  match = rx.Search()
End While

I assume this is intentional by Xojo, because it’s mentioned in the docs:

Val returns zero if the string contains no numbers, except in the special case where the string begins with the string “NAN”. In this case, it returns “NAN(021)”.

But I agree with you to the extent that an NaN should only be recognized if it is written as “NaN”, followed by no letter…

A RegEx i posted in another Thread, may be a bit better suited for your needs:

Var sourceText As String = "v. 15.4 → Naniser 12 8.333"
Var myDouble() As Double

Var rx As New RegEx
rx.SearchPattern = "(?mi-Us)\d+([.,]\d+)?"

Var rxOptions As RegExOptions = rx.Options
rxOptions.MatchEmpty = False
rxOptions.StringBeginIsLineBegin = False
rxOptions.StringEndIsLineEnd = False

Var match As RegExMatch = rx.Search( sourceText )
While match IsA RegExMatch
  
  myDouble.Add match.SubExpressionString(0).ToDouble
  
  match = rx.Search // Fetch the next match
Wend

This one extracts multiple decimals from any string.

Sure it isn’t that, and nobody suggested otherwise. Rather the string gets interpreted as “Nan” (which is the representation of a number in Xojo even though it is “NaN”, i.e. “Not a Number”) followed by “iser” (which even Xojo doesn’t regards as a number).

You mean a possible representation of a number must be separated from non-number content by whitespace? But in that case “123abc” wouldn’t be regarded as containing the number 123 either. Or should it be just “NaN”, “INF”, and “-INF” that must be separated by whitespace?

This :slight_smile: