1

I have an application that reads in a number via ajax, the number is hexadecimal and I parse it and convert to decimal.

The numbers come in through a wireless serial link and are not 100% reliable so I need to check them before I start processing the data. The numbers take the form ****025781610403e5**** for example. The **** is just a way of checking the start and end of the number that I have used in the past with non web based projects and could be changed.

Anyway to my question at last: As part of error checking I thought I would check for NaN as I do get NaN errors when I have been testing but while *1234 gives a positive NaN 12**34 does not, why is that? and what else can I do to test?

Here is some of the code I have used, please note I am fairly new to javascript.

function readSliceConvert()
{
    functionReadForm()
    testVal = hexString.slice(4,18);
    document.getElementById("battDb4").innerHTML=testVal;
    testNum1 = h2d(testVal)
    document.getElementById("battDb5").innerHTML=testNum1.toString();
    testNum2 = parseInt(testVal);
    document.getElementById("battDb6").innerHTML=testNum2.toString();
    if (isNaN(testNum2))
    {
        errorCount++;
        document.getElementById("battDb3").innerHTML=errorCount.toString();
        document.getElementById("battDb4").innerHTML=testVal;

        return;
    }
}
2
  • 2
    isNaN('12**34') === true & isNaN('*1234') === true Commented Nov 15, 2012 at 20:43
  • isNaN('12**34'); returns true, you have something else off. Commented Nov 15, 2012 at 20:50

3 Answers 3

3

That's because you are using parseInt, it will silently ignore characters at the end of the string when there are some digit in the beginning of the string that it can parse.

I don't know what your h2d function is doing, but it seems that you are converting the hexadecimal string to a number, then to a string in decimal form, then back to a number. I don't see any reason why the output of parsing the hexadecimal string couldn't be a number.

For example like this, returning null if the parsing fails:

function h2i(str) {
  var num = 0;
  var digits = "0123456789abcdef";
  str = str.toLowerCase();
  for (var i = 0; i < str.length; i++) {
    var n = digits.indexOf(str.substr(i, 1));
    if (n == -1) return null;
    num = num * 16 + n;
  }
  return num;
}

Demo: http://jsfiddle.net/Guffa/6yAaP/

Usage:

testVal = hexString.slice(4,18);
document.getElementById("battDb4").innerHTML = testVal;
testNum = h2i(testVal)
document.getElementById("battDb5").innerHTML = testNum.toString();
if (testNum == null)
{
  errorCount++;
  document.getElementById("battDb3").innerHTML = errorCount.toString();
  document.getElementById("battDb4").innerHTML = testVal;
  return;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the code sample I am trying this out, not quite sure what's going on but getting there, as I said I am new to this.
@Simon_A: I added a usage example above, hope it helps.
0

Do you know what parseInt() does?

From MDN

parseInt is a top-level function and is not associated with any object.

The parseInt function converts its first argument to a string, parses it, and returns an integer or NaN. If not NaN, the returned value will be the decimal integer representation of the first argument taken as a number in the specified radix (base). For example, a radix of 10 indicates to convert from a decimal number, 8 octal, 16 hexadecimal, and so on. For radices above 10, the letters of the alphabet indicate numerals greater than 9. For example, for hexadecimal numbers (base 16), A through F are used.

If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point. parseInt truncates numbers to integer values. Leading and trailing spaces are allowed.

Run the code in the console

console.log( parseInt("12**34",10) );  

So you are running isNaN against a number since parseInt returns 12.

When you have the * as the first character, there are no leading numbers to return.

console.log( parseInt("*1234",10) );  

1 Comment

Thanks for that, I have just learned what console.log does, I said I was new to this;)
0

You're seeing weird behaviour because isNan is broken (see the mozilla docs for details).

A better way to test your data is correctly formatted would be a quick regular expression, like serial.test(/^\d+$/), which will succeed if the entire serial is entirely numeric, or serial.test(/^\*{4}\d+\*{4}$/) which will succeed if the serial is four asterisks, followed by one or more number, followed by another four asterisks.

Update: @Guffa's answer is correct, and should be accepted, but I'll leave this here as I think there's a valid argument in the bigger picture that you could better accomplish what you're trying to do with a regular expression.

Running test on the string executes the supplied regular expression, and returns true if it matches the string.

Regular expressions are just patterns describing text, which can be incredibly complex or as simple as the example I've given (\d+ means match a number (\d) one or more times (+), with anchors for the beginning (^) and end ($) of the string to indicate that we want to match the whole string, not just part of it. They're ridiculously useful, so it's almost certainly worth taking the time to learn the basics of how they work, and expand you knowledge over time. There's a great tutorial on regular-expressions.info that'll get you started in no time.

6 Comments

No, the isNaN is only broken in the sense that it gives confusing result when you don't know what you are sending into it. In this case it's always the result of parseInt so the type of the value is known, and the is no problem with using isNan.
I wouldn't say isNaN is broken anymore than === or == are broken it just has quirks you need to understand.
Missed the parseInt in his code, good catch. I'd still argue that his technique isn't the best, but you're right.
@Chad perhaps, but then there's a very fine line between a quirk and a bug. Mozilla describes it as broken, and the behaviour's broken/quirky enough for it to be unpredictable at times, so as a rule I tend to advise against it.
@Kelvin Mackay serial.test(/^*{4}\d+*{4}$/) - This looks good/interesting, but I have very little idea what it's doing, or how it's doing it rather.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.