Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
QuarkJets
Sep 8, 2008

PhantomOfTheCopier posted:

You people sure have some strange reading problems. Matlab is an application. It is perfectly reasonable for it to return calculations that adhere most closely to standard practice of significant digits. Nothing prevents and nothing I wrote prevents intermediate and internal calculation to be handled differently. Real number results are handled differently than integers (which I said nothing about). Nothing prevents an idiot with a computer programming language from specifically requesting the wrong value for 2pi. I'm sure some legislator would have been happy to have such an app.

As to the bot poster who replies immediately to every word I write, thank you for being a follower but a straw man argument simply will not do. Differences between large and small numbers are very important, and this I acknowledged in my original comment (which you apparently failed to actually read). Anyone who writes code to handle those situations, including moon mirror fluctuations, assuming that a double in a standard statically typed computer programming language (which is NOT a mathematics application, so different than what was being discussed) is sufficient for their needs will have their crappy code posted here.

Now I know why people like agile development; it's because they couldn't possibly write code based on a specification they'd have to read.

If you wanted to exclude integers from your argument then you should have said so. Regardless, your argument still applies to integer precision whether you like it or not, and the same counterarguments apply to downcasting floating point precision.

It looks like everyone read your post very accurately, you're just upset that people don't agree with you. Further, did you read my post? Because I'm suggesting that it would be fine to downcast if Matlab at least threw a warning at the user telling them that it was doing so; then the intention of MathWorks is explicit when 2 different precision levels smash into each other instead of silently giving you less precision than you may have expected.

Further, you're mixing up terms in order to try and give yourself a point that you didn't make initially; significant digits are not the same as numerical precision, and a number being written as float32 does not mean that its significance includes all of float32's precision range, nor does it mean that its significance is limited to that range (as an example, consider the number of significant digits to the number 1 when stored in float32; why does multiplying the float32 representation of 1 by a number using the entirety of float64 precision cause me to lose precision? Downcasting that result to float32 is in fact unreasonable)

QuarkJets fucked around with this message at 08:28 on Sep 29, 2017

Adbot
ADBOT LOVES YOU

Zemyla
Aug 6, 2008

I'll take her off your hands. Pleasure doing business with you!

Eela6 posted:

you're real dumb, hth

He's double dumb, in fact.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

QuarkJets posted:

If you wanted to exclude integers from your argument then you should have said so. Regardless, your argument still applies to integer precision whether you like it or not, and the same counterarguments apply to downcasting floating point precision.

Without expressing any view on the rest of PhantomOfTheCopier's arguments, it doesn't seem to me that this is the case. "integer precision" really means range of representable values, not precision per se, whereas floating-point precision is precision per se. Given a range of integer values, there is only one possible degree of precision that we would expect to be made available by an integer data type supporting that range, which is to say: absolute precision. The argument that spurious precision should be avoided when dealing with floating-point numbers doesn't apply to integers, where the notion of spurious precision does not apply.

Volte
Oct 4, 2004

woosh woosh

QuarkJets posted:

(as an example, consider the number of significant digits to the number 1 when stored in float32; why does multiplying the float32 representation of 1 by a number using the entirety of float64 precision cause me to lose precision? Downcasting that result to float32 is in fact unreasonable)
Why is that unreasonable? The number 1.0 in float32 could represent any real number in [1, 1+2-23). By upcasting it to a float64, you're arbitrarily restricting that to a much smaller sub-range [1, 1+2-52) without any justification.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



TooMuchAbstraction posted:

Let us never lose sight of the fact that Matlab is a terrible, awful programming language that only survives because it has so goddamn many scientific/mathematical libraries bolted onto it.

And now it's tearing our happy thread apart. Truly its horror knows no bounds.

Doom Mathematic
Sep 2, 2008
I'm getting really confused here. The number 1.0, as a float32, precisely represents the real number 1, to as many decimal places as you want. Upcasting to float64 doesn't alter that. But at least two people in this thread have said the opposite.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Doom Mathematic posted:

I'm getting really confused here. The number 1.0, as a float32, precisely represents the real number 1, to as many decimal places as you want. Upcasting to float64 doesn't alter that. But at least two people in this thread have said the opposite.

It's not about the decimal representation at all.

What's the closest representable float to 1+2-50? What about the closest representable double?

Doom Mathematic
Sep 2, 2008

Jabor posted:

It's not about the decimal representation at all.

What's the closest representable float to 1+2-50? What about the closest representable double?

I don't know, what?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
A related question, that might make things easier to understand if you tackle it first: What's the smallest representable float that's bigger than 1.0?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Doom Mathematic posted:

I'm getting really confused here. The number 1.0, as a float32, precisely represents the real number 1, to as many decimal places as you want. Upcasting to float64 doesn't alter that. But at least two people in this thread have said the opposite.

The point is that if the result of a calculation is the float32 1.0, that means that the "true answer" to the calculation was in a certain interval on the number line which includes the real number 1. If you then make it a float64 then it might appear to a consumer as though the "true answer" lies in a smaller interval (because float64 has greater precision than float32). Maybe it does, maybe it actually is a number which converted suitably into a float64 would end up as something other than 1.0.

Jethro
Jun 1, 2000

I was raised on the dairy, Bitch!
If you try to represent the number 1.0000000001 as a float32, it will be truncated to 1.0. If you then use that 1.0 to do perform operations with a float64, you will get a different answer than you would had you put 1.0000000001 in a float64 to begin with. If the result is a float64, you may think you've got the precision of a float64 when your precision is really only that of the float32 you started with, and any digits outside of that are spurious.

That said, the solution to a programmer making such a mistake is still probably not to silently downcast to float32. Silently limiting the range of possible results and throwing away digits is not a good way to handle the fact that some of those digits might not be correct in some rare circumstances. And it's definitely always wrong when we're talking about integer types.

Pollyanna
Mar 5, 2005

Milk's on them.


The La Mulana 2 team posted an update on their progress:

quote:

At the beginning of development, we had planned to let Lumisa talk with all the NPCs by pressing a button when near them, but considering our code, it was very difficult to implement and we had to omit that. Instead, we changed the system to start the conversation automatically when Lumissa gets near those guide NPCs or enters the event area.  

:psyduck: I have no idea how code can be that inflexible, but what do I know.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Pollyanna posted:

The La Mulana 2 team posted an update on their progress:


:psyduck: I have no idea how code can be that inflexible, but what do I know.

lol Kickstarted games are probably just automatic coding horrors

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


That reminds me, someone put together a primer on the programming language Jonathan Blow has been making.

I don't actually think it's a horror, though it is always a bit shocking to see the work of programmers in a sub-field with completely different demands and desires.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
We have a bunch of places in code where we want to switch on an enum and not miss any cases (I assume this is not wildly out of the ordinary). Until today I wasn't aware that MSVC supported this:

code:
#pragma warning(push)
#pragma warning(error: 4061) // Enforce exhaustive switch on enum
switch (myEnum)
{
    ...
}
#pragma warning(pop) // Stop enforcing exhaustive switch on enum
We've been relying on runtime ASSERTs in the default branch of the switch. It's me, it's us, we are the coding horror.

CPColin
Sep 9, 2003

Big ol' smile.
code:
    DateWork = string.Format("{0:yyyy-MM-dd}", FromDate);
    FromDate = DateTime.Parse(DateWork);
    DateWork = string.Format("{0:yyyy-MM-dd}", ToDate);
    ToDate = DateTime.Parse(DateWork);
:sigh:

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



CPColin posted:

code:
    DateWork = string.Format("{0:yyyy-MM-dd}", FromDate);
    FromDate = DateTime.Parse(DateWork);
    DateWork = string.Format("{0:yyyy-MM-dd}", ToDate);
    ToDate = DateTime.Parse(DateWork);
:sigh:

Clipping off the hours, minutes, seconds, etc?

The Fool
Oct 16, 2003


Pollyanna posted:

The La Mulana 2 team posted an update on their progress:


:psyduck: I have no idea how code can be that inflexible, but what do I know.

My guess is that they have a problem with an underlying system that makes it difficult to identify which NPC is the one you're trying to interact with.

Where, with their stated solution, to trigger a conversation whenever you are in range, they don't need to be specific, they can just grab every entity in a certain radius.

I'm saying this with no information about the game itself.


Munkeymon posted:

lol Kickstarted games are probably just automatic coding horrors

All games are coding horrors.

dwazegek
Feb 11, 2005

WE CAN USE THIS :byodood:

CPColin posted:

code:
    DateWork = string.Format("{0:yyyy-MM-dd}", FromDate);
    FromDate = DateTime.Parse(DateWork);
    DateWork = string.Format("{0:yyyy-MM-dd}", ToDate);
    ToDate = DateTime.Parse(DateWork);
:sigh:

What's the context for this?

The datetime-to-string-to-datetime is real dumb, but I can forgive someone for not knowing about the Date property and coming up with an alternative (although this might break based on culture).

Going by .NET naming conventions, FromDate, ToDate and DateWork are (public) properties, which seems to point to far more horrors.

quiggy
Aug 7, 2010

[in Russian] Oof.


The Fool posted:

All games are coding horrors.

C code:
float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;

	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y;                       // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the gently caress? 
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//	y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

	return y;
}

Zopotantor
Feb 24, 2013

...und ist er drin dann lassen wir ihn niemals wieder raus...

PhantomOfTheCopier posted:

You people sure have some strange reading problems. Matlab is an application.
Some people are treating it as a programming language.
Hell, some of my own colleagues use it for chip design. :shepicide:

Volte
Oct 4, 2004

woosh woosh

Doom Mathematic posted:

I'm getting really confused here. The number 1.0, as a float32, precisely represents the real number 1, to as many decimal places as you want. Upcasting to float64 doesn't alter that. But at least two people in this thread have said the opposite.
The knowledge that a particular float is an exact encoding of a particular real number is external information that can't possibly be captured by the float itself. Yes, you can encode the real number 1 in a float32 and be confident that when you read it back later, you didn't lose anything. But if you get the float32 1.0 as the result of a computation -- even if it's a computation carried out in arbitrary precision or even by hand -- you have no way of knowing if the answer is really 1.0 or if it is 1.0 + 2-40. If you then carry that result forward into 64-bit precision by implicitly upcasting, you're also implicitly dropping that uncertainty, which has no mathematical justification. It might not have a practical impact on what you're doing, and in many cases it may be unavoidable, but it's important to at least be aware that it's happening.

CPColin
Sep 9, 2003

Big ol' smile.

Munkeymon posted:

Clipping off the hours, minutes, seconds, etc?

dwazegek posted:

What's the context for this?

Yeah, this is adjusting a value retrieved from a database, so stripping off the time portion is what I'm guessing, too.

dwazegek posted:

The datetime-to-string-to-datetime is real dumb, but I can forgive someone for not knowing about the Date property and coming up with an alternative (although this might break based on culture).

Going by .NET naming conventions, FromDate, ToDate and DateWork are (public) properties, which seems to point to far more horrors.

That DateWork identifier is a local variable:

code:
string DateWork = string.Empty;
Never mind the initialization to string.Empty instead of "" or the fact that the initialization is unnecessary altogether. Also never mind that the variable doesn't need to exist at all! Neither FromDate nor ToDate has any access modifiers, so I guess that capitalization is misleading!

Dirty Frank
Jul 8, 2004

Hammerite posted:

We have a bunch of places in code where we want to switch on an enum and not miss any cases

I've just done this in the last week; I moved the switch into its own method and then a unit test that checks for all enum values a non null object is returned and no exceptions are raised.

Mr Shiny Pants
Nov 12, 2012

Doc Hawkins posted:

That reminds me, someone put together a primer on the programming language Jonathan Blow has been making.

I don't actually think it's a horror, though it is always a bit shocking to see the work of programmers in a sub-field with completely different demands and desires.

I like Jonathon Blow, I've been following his talks about the why and how of his programming language and I must say that the reasoning behind it is usually pretty good. He also makes it really easy to understand some fundamental issues with C++ and game engines in general.

Especially the bit with the Structs of Arrays and Arrays of Structs and why you want only a subset of the properties of your classes, the ones that have transforms for example which get updated every frame, in a smaller data structure that can live in the CPU cache.

Listening to the Unite 2017 talk about Unity3d and the implementation of its job system, reminded me of what he was talking about.

Plus he makes me feel a better programmer because he does some live programming and you can see the mistakes he makes and the thinking process he goes through. :)

PhantomOfTheCopier
Aug 13, 2008

Pikabooze!

PhantomOfTheCopier posted:

The fact that a math focused application ensures results introduce no false precision is entirely reasonable and good. If x=pi is a single, y=pi is a double, then x+y can only ever be 2pi to the precision of a single. Returning x+y as a double is just wrong.
Sorry I didn't use the words "significant digits" here, but in an applied mathematics application, I still say it's not unreasonable. The assumption in empirical values is that you cannot introduce unmeasured precision:
code:
  float a=M_PI;
  double b=M_PI;
  float c=a+b;
  double d=a+b;
  printf("d-c=%e\n",d-c);

d-c=-8.742278e-08

Actual error in a:  28ppb
Actual error in b:  ~0ppb
Actual error in c:  28ppb
Actual error in d:  14ppb
Upping to the double has introduced some false precision, which can now propagate onward into other exciting calculations, which will produce some interesting results when large values are multiplied here. Of course, pi has infinite precision as needed, but for measured or statistical values, this doesn't seem to be an unreasonable behavior at all.

Zemyla posted:

Clearly, we should represent all real values as lazy infinite continued-fraction lists.
It's not a bad idea; people like arrays, and what difference does it really make if it's a mantissa base10 or mantissa-a-la-continued-fraction? :buddy: Based on the current preponderance of opinion in the thread, this is the way a programming/application* language should always behave by default (* I'm not sure which, because I think people are still confusing comments about an application with comments about a programming language):
code:
decimal4 a=1001;
a*=a; // 1002001 decimal7
a*=a; // 1004006004001 decimal13
a*=a; // 1008028056070056028008001 decimal25
a*=a; // 1016120561824376019452881448012369820560120016001 decimal49

quote:

Integers...
Electronic counters are very concerned with precision +-1, obviously, but it only takes 43 bits to handle 1000 seconds of rubidium oscillation, and that may well be the most precise measurement currently obtained. In some cases it's easier to use more expensive counters that can handle the higher frequencies, and overflow trigger into cheaper equipment to handle the millions/billions/&c. Conveniently, none of this gets even close to worrying about 64-bit upscaling to 128bit.

Jethro posted:

That said, the solution to a programmer making such a mistake is still probably not to silently downcast to float32.
A scientific programmer should be very, very concerned, indeed, and should well be preventing hours of wasted time and money on debugging issues that should have been prevented by over/underflow avoidance, tracking actual measurement precision, and so forth. A Matlab user may well not recognize that their result suddenly has more precision with a 64-bit result, particularly if they were specifically requesting only 32-bits for one of their values in the first place. I honestly don't see much difference in grievance possible with a (float+double) downcast versus upcast in an application; should it warn on upcasting as well? For a computer programming language, on the other hand, I think the thread has room for a few examples where people have flubbed their floats.


Everyone enjoy their approximately (float)0.33*(length_of_day) of work today!

Ranzear
Jul 25, 2013

quiggy posted:

C code:
float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;

	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y;                       // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the gently caress? 
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//	y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

	return y;
}

That's no horror, that's just implementing Fast Inverse Square Root. The comments are an acceptable reaction to such sorcery.

Edit: Oh hey, that's actually the Quake 3 code, on the wiki page.

Ranzear fucked around with this message at 18:29 on Sep 29, 2017

Aramis
Sep 22, 2009



quiggy posted:

C code:
float Q_rsqrt( float number )
{
	long i;
	float x2, y;
	const float threehalfs = 1.5F;

	x2 = number * 0.5F;
	y  = number;
	i  = * ( long * ) &y;                       // evil floating point bit level hacking
	i  = 0x5f3759df - ( i >> 1 );               // what the gently caress? 
	y  = * ( float * ) &i;
	y  = y * ( threehalfs - ( x2 * y * y ) );   // 1st iteration
//	y  = y * ( threehalfs - ( x2 * y * y ) );   // 2nd iteration, this can be removed

	return y;
}

What I particularly hate about this is that it's still treated by many people as a legit optimization instead of a historical curiosity when:

1. There are much better ways to do this nowadays with compiler intrinsics.
2. It's actually illegal code in C++, which is what these coders are actually using.

Athas
Aug 6, 2007

fuck that joker

Aramis posted:

2. It's actually illegal code in C++, which is what these coders are actually using.

I am pretty sure it is illegal C, too. That cast from float pointer to long pointer is undefined behaviour. I seem to recall you need to use memcpy() for such tricks if you want your code to be legal.

Aramis
Sep 22, 2009



Athas posted:

I am pretty sure it is illegal C, too. That cast from float pointer to long pointer is undefined behaviour. I seem to recall you need to use memcpy() for such tricks if you want your code to be legal.

You can make it legal C using a union IIRC.

CPColin
Sep 9, 2003

Big ol' smile.
More, from the same file:

code:
    // run last 6 months
    for (int count = 0; count <= 6; count++)
    {
        ...
    }
Why yes, that does run for the last seven months, instead!

The Fool
Oct 16, 2003


There are three types of programmers in the world.

Those who make off-by-one errors and those who don't.

Eggnogium
Jun 1, 2010

Never give an inch! Hnnnghhhhhh!

CPColin posted:

Yeah, this is adjusting a value retrieved from a database, so stripping off the time portion is what I'm guessing, too.


That DateWork identifier is a local variable:

code:
string DateWork = string.Empty;
Never mind the initialization to string.Empty instead of "" or the fact that the initialization is unnecessary altogether. Also never mind that the variable doesn't need to exist at all! Neither FromDate nor ToDate has any access modifiers, so I guess that capitalization is misleading!

What's wrong with using string.Empty instead of ""? Or an unneeded initialization? Seems pedantic to care about such things.

Rubellavator
Aug 16, 2007

I once wrote a unit test that dealt with time in the form of now vs a future date. Rather than making sure that future date was now + x months, I arbitrarily and lazily picked the month of june, because it was currently march. Imagine what happened in June.

CPColin
Sep 9, 2003

Big ol' smile.

Eggnogium posted:

What's wrong with using string.Empty instead of ""? Or an unneeded initialization? Seems pedantic to care about such things.

string.Empty is more typing than "" and unneeded initialization makes the processor do more work than it needs to. Without the unneeded initialization, I wouldn't even have had to bring up the use of string.Empty and I wouldn't be typing this post! See how much waste it is?

quiggy
Aug 7, 2010

[in Russian] Oof.


Aramis posted:

You can make it legal C using a union IIRC.

Yeah you could legally rewrite the cast in C/C++ with:
C++ code:
union {
    float y;
    long i;
} u;

u.y = number;
u.i  = 0x5f3759df - ( u.i >> 1 );

// do whatever with u.y;
C++ also allows you to do some weird stuff with reinterpret_cast that can let you access the bits of a float or double, although the union trick tends to be a bit more legible.

Eggnogium
Jun 1, 2010

Never give an inch! Hnnnghhhhhh!

CPColin posted:

string.Empty is more typing than "" and unneeded initialization makes the processor do more work than it needs to. Without the unneeded initialization, I wouldn't even have had to bring up the use of string.Empty and I wouldn't be typing this post! See how much waste it is?

Yeah, but like, who cares? Half the stuff you've posted in this thread is so minor it just seems like you have a bug up your rear end. Do you actually get anything done obsessively grooming minor inefficiencies out of your code?

CPColin
Sep 9, 2003

Big ol' smile.
Hello, welcome to the "Coding horrors" thread!

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



It is very :smith: to start at a new place and start seeing stuff like that all over the place.

Adbot
ADBOT LOVES YOU

Jeb Bush 2012
Apr 4, 2007

A mathematician, like a painter or poet, is a maker of patterns. If his patterns are more permanent than theirs, it is because they are made with ideas.

CPColin posted:

Hello, welcome to the "Coding horrors" thread!

caring about the processor doing a completely irrelevant amount of extra work is a coding horror

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply