0

So I have a C# web api endpoint that returns a C# decimal value which is 49.10. So we return it into a VB.NET webforms application and the return result comes out as 49.1 even though they are both of primitive type decimal.

What really make this issue odd is we have 2 local machines with the same code on each one and on my machine it's returned as 49.10, but on colleagues machine it's returned as 49.1.

Really puzzling situation that cannot seem to get to the bottom of and wondered whether anyone has come across this and knows what I am missing.

C# Model is like this...

[DataContract(Namespace = "")]
[Serializable]
public class TestClaim
{
   [DataMember(EmitDefaultValue = false)]
   public decimal VoucherSupplementFirstPair { get; set; }
}

VB.NET Model is like this...

<Serializable()>
Public Class TestClaim
   Public Property VoucherSupplementFirstPair As Decimal
End Class

The reason I'm asking is because it works on one machine and not on another, so it's like something to do with windows settings maybe?? I thought the CLR would handle something like this.

Thanks for any advise.

Whistler1
  • 47
  • 7
  • Please share a [mcve]. – mjwills Jul 22 '20 at 13:51
  • `and the return result comes out as 49.1` What do you mean by `comes out`? How are you visualising it? – mjwills Jul 22 '20 at 13:52
  • Assuming you are running in a Windows environment, check the settings on the workstation? https://www.softwareok.com/?seite=faq-Windows-10&faq=146 – Pete -S- Jul 22 '20 at 13:54
  • 1
    Mathematically they are the same. If you _choose_ to visualize trailing zeroes, you will see them, but usually they are not shown. (Otherwise, why expect 49.10 instead of 49.100?) – oerkelens Jul 22 '20 at 14:00
  • Ok for those that can't get to grips with this. C# WebAPI endpoint returns decimal value 49.10. It's returned into VB.NET decimal datatype as 49.1 not 49.10. This is how it is on one machine whereas on another machine it is correct. The is no need for anything more extensive, the information is clear. – Whistler1 Jul 22 '20 at 14:05
  • 1
    `49.10` is a formatting option (so, a string). Currency representation, for example. Or other forms of presentation that imply a *format*. The *number* is `49.1` (as you cannot have a number presented as `049.1`, if you don't format it). – Jimi Jul 22 '20 at 14:08
  • 1
    Could be you're seeing an effect of the decimal internal representation exponent retaining an additional digit in the 49.10 case. See https://stackoverflow.com/questions/15348938/vb-c-decimal-internal-format. But it's not something to worry about (mathematically). The values are the same. – MarkL Jul 22 '20 at 14:13
  • 1
    @Jimi A thing to keep in mind is that with `decimal` _specifically_ 10.1M and 10.10M (and 10.1000M etc etc) are stored differently in memory. They aren't the exact same value (although `==` will return true for them). Hence why https://dotnetfiddle.net/D2Jy76 . Interestingly, VB.NET does appear to act differently. https://dotnetfiddle.net/dXNaOY – mjwills Jul 22 '20 at 14:20
  • Thanks for all your advise, you've given me loads to be getting on with, much appreciated. – Whistler1 Jul 22 '20 at 14:22
  • 1
    @mjwills One thing about your vb.net example, the VS ide will change the `10.10D` constant to `10.1D`. But you can see the zero 'retained' by adding `5.05D` to itself. See https://dotnetfiddle.net/pSzPci. This example also demonstrates that in decimal variables `10.1` is equal to `10.10`. – MarkL Jul 22 '20 at 14:38
  • 1
    @MarkL That is correct. The point I was making is that some people think that 10.1 and 10.10 are literally stored in memory as the same value. That isn't the case with `Decimal` (as shown by your sample where you got two different 10.1 values). That being said, I am assuming that datacontracts are doing something more akin to `Decimal.Parse` (i.e. framework specific, not language specific) so I am still not 100% clear why language matters. https://dotnetfiddle.net/FrTnlh – mjwills Jul 22 '20 at 14:40
  • 1
    @mjwills Agreed. I also don't see why/how the language would matter. I'd expect this behavior is completely encapsulated and implemented in the framework classes, not the generated runtime code from the particular vb.net or c# source. – MarkL Jul 22 '20 at 14:46

1 Answers1

1

I've been working with VB.Net for a while now. For double/decimal, Vb will automatically truncate zeroes since they are not significant. If you want to display 2 decimal points then use the FormatNumber(i, x) function.

Albert Alberto
  • 801
  • 8
  • 15