Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect output in toHexString applied to Byte and Short values #10216

Closed
scabug opened this issue Feb 28, 2017 · 23 comments
Closed

Incorrect output in toHexString applied to Byte and Short values #10216

scabug opened this issue Feb 28, 2017 · 23 comments

Comments

@scabug
Copy link

scabug commented Feb 28, 2017

This is my very first issue submission to Scala, so I apologize in advance for any mistakes I might have made in filling out the different fields.

Calling toHexString method on numeric types other than Int will produce unexpected output. I believe that toHexString is not implemented in Byte and Short and an implicit conversion to Int is happening.

scala> -1.toByte.toHexString
res2: String = ffffffff
// should be "ff"

scala> -1.toShort.toHexString
res3: String = ffffffff
// should be "ffff"

scala> -1.toHexString
res4: String = ffffffff
// is correct

scala> -1.toLong.toHexString
res5: String = ffffffffffffffff
// is correct
@scabug
Copy link
Author

scabug commented Feb 28, 2017

Imported From: https://issues.scala-lang.org/browse/SI-10216?orig=1
Reporter: Alexandre Sieira (asieira)
Affected Versions: 2.12.1

@scabug
Copy link
Author

scabug commented Mar 1, 2017

@som-snytt said:
It's also not implemented on Int. Using tab completion after the print comment:

scala> 42.toHexString //print
   scala.Predef.intWrapper(42).toHexString // : String

scala> -1.toByte.toHexString //print
   scala.Predef.intWrapper(-1.toByte.toInt).toHexString // : String

There is no java.lang.Byte.toHexString but formatting does what you want:

scala> f"${-1.toByte}%x"
res0: String = ff

I'm not sure there is a welcome tag for the label field like they have on github.

@scabug
Copy link
Author

scabug commented Mar 8, 2017

Nilay Pochhi (npochhi) said (edited on Mar 8, 2017 7:34:08 PM UTC):
Hi, I'd like to take up this task. I'm bit of a beginner (cloned the repo and built the project last week) and found this task relatively easy. :) So, basically I've to implement this function in RichByte.scala in scala/src/library/scala/runtime, right?

@scabug
Copy link
Author

scabug commented Mar 8, 2017

@SethTisue said:
there is discussion at https://gitter.im/scala/contributors?at=58c075a1567b0fc8138fbba6 about whether it's a good idea to make this work, or whether it would be better to just deprecate toHexString entirely, and instead recommend people explicitly call java.lang.Integer.toHexString, java.lang.Long.toHexString, and so forth.

@atiqsayyed
Copy link

@SethTisue I'm confused after going through the discussions, is it concluded that the toHexString function would be deprecated??

@Ichoran
Copy link

Ichoran commented Aug 18, 2017

I'm not convinced deprecation is a better solution than making it work properly for every numeric type, like we do with min and max and so on.

@atiqsayyed
Copy link

@Ichoran it makes sense not to deprecate it rather find a proper solution for it

@som-snytt
Copy link

toBinaryString and toOctalString show the same behavior. Hence the sense of whack-a-mole in the previous discussion.

@Ichoran
Copy link

Ichoran commented Aug 18, 2017

All the moles need to be whacked. There aren't that many of them. You don't need to pave everything over with concrete to solve the problem.

@niebloomj
Copy link

What is the conclusion? Deprecating toHexString or creating the richness for the other types?

@niebloomj
Copy link

@Ichoran

@som-snytt
Copy link

In every generation, one is chosen to whack the moles. Endowed with extraordinary skill and patience, a whacker will rise after some years to find the moles and then whack them, and the moles will fall.

@niebloomj
Copy link

lol i just want a first issue to work on haha

@martijnhoekstra
Copy link

martijnhoekstra commented May 28, 2019 via email

@niebloomj
Copy link

Can someone assign this to me so that there isn't duplicated work? Thank you. The moles will be whacked.

@NthPortal
Copy link

Please consider this ticket assigned to you. GitHub only allows assigning to organisation members, but if someone else looks at this ticket they will see your comment.

@nogurenn
Copy link

nogurenn commented Aug 27, 2019

So if I understand this correctly, numeric types get implicitly converted to their respective respective RichX, which in the case of using toHexString() ends up in implicit conversion to RichInt or RichLong, and then performs java.lang.(Integer|Long).toHexString. Is that right?

For RichByte.toHexString, I think something like this should be enough?

scala> java.lang.Integer.toHexString(java.lang.Byte.toUnsignedInt(-1))
res71: String = ff

For converting short to hex, I'm not sure how to go about implementing it for the PR. I don't understand why the second style works though. Is something like this okay, or should there be guarantee that what comes in to the method is a scala.Short?

scala> java.lang.Integer.toHexString(-1 & 0xffff)
res28: String = ffff

scala> java.lang.Integer.toHexString(-1.toShort & 0xffff)
res31: String = ffff

@NthPortal
Copy link

@nogurenn both of those implementations look pretty reasonable. I believe there is a j.l.Short.toUnsignedInt though, so, you might also implement the RichShort one using that, for consistency

@nogurenn
Copy link

nogurenn commented Aug 28, 2019

@NthPortal Wait, it just hit me. Does this imply we also need to work out stuff for toBinaryString and toOctalString? Those other two methods short-circuit to RichInt and RichLong as well.

@NthPortal
Copy link

scala> -1.toBinaryString
res0: String = 11111111111111111111111111111111

scala> -1.toByte.toBinaryString
res1: String = 11111111111111111111111111111111

@nogurenn yes

@som-snytt
Copy link

som-snytt commented Aug 29, 2019

Sorry I missed the updated conversation. I gave this a nudge.

Maybe the test could be further improved as an exercise? Normally you would expect a junit test, but I left it as partest because of possible issues around widening or implicit selection, it's better to test the compiler being built.

@nogurenn the rules for the numeric ops are https://scala-lang.org/files/archive/spec/2.13/12-the-scala-standard-library.html#numeric-value-types where it says the short gets promoted to int first. The constant arg in -1.toShort & 0xFFFF is already an int; you might expect it would be taken as short, but no.

@som-snytt
Copy link

som-snytt commented Aug 29, 2019

Forgot to add that the fix is not binary compatible. Luckily 2.14 milestone is due by end of the year.

Edit: famous last words.

@som-snytt
Copy link

Not only is this out of scope for Scala 2, the PR was never merged at scala-library-next.

@som-snytt som-snytt closed this as not planned Won't fix, can't repro, duplicate, stale Nov 12, 2023
@SethTisue SethTisue removed this from the 3.x milestone Nov 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants