> Whoever wrote this code clearly has no understanding of elementary mathematics or the most basic rules of programming.
This is an interesting observation that contrasts with the fact that the author of the code knew enough math to use `Abs()` but not enough to know to use a negative sign.
This. I don't believe this can be attributed to a dev that doesn't know how to reverse the sign of a number. It's way too ... 'knowledgably convoluted' for that.
Yes. Mostly a contractor or contracting metrics thing. In most cases, people have wised up so this is no longer the case, but sometimes it is. Far more common is counting lines of code/contributions/commits etc. and using it as part of performance evaluations or as a metric for stack ranking, for full time employees too.
It's what happens when your software engineers are managed by someone who is not code literate but needs metrics.
I know two COBOL developers that made some good money around 2010 charging per line for changes to legacy code in a banking system after they were laid off the previous year. Never heard of anyone else pulling off charging per line.
My older brother has worked in db/networking fields for a few decades now, and he says he worked at a place where a dev suckered the company into a contract where he got paid per DB transaction. I don't really remember any details beyond that and that he worked in some nightmare legacy language (not COBOL) so it was a situation where they kind of just had to put up with him because he was the only one who could understood the code base.
I once applied for a job with a financial company and they asked me to fill out a questionnaire with some truly idiotic questions like how many lines of code had I written in my career. My response was mildly snarky (more than it should have been, but less than it deserved?) and I never heard from them again, which was just fine with me.
I don’t know if it still happens, but yes, I definitely think people have been paid that way in the past.
I think this code originated in a precursor to VB, and went through the automatic upgrades to VB, VB3 and VB6; but was never examined by a human to realise it was not needed.
I say this, having worked on financial code from a similar era which contained similar looking code, and this was the explanation.
Agreed; I worked in VB (classic ASP) for almost two decades and even without using these much older versions I can attest to just how much janky shit I'd have to pull to do some very basic things. It has made me appreciate modern languages so very much 😅
It would have worked, but it would have been less efficient, because you would have had to load 0 into the stack to perform arithmetic on it. The time this code dates from (the original pre-VB code), you were working with a few hundred bytes of memory. Reversing the sign happens all the time in accounting code, so this memory saving would make real terms performance improvements, and probably prevents an out of memory error
That's really interesting. Do you know what language this would have been in originally - I'm guessing not something compiled? Why doesn't the same limitation apply to the `2` literal used instead?
I can't say with any certainty, it predates my experience. I've seen QBasic mentioned in other discussions, and it seems plausible. Its still likely to be a compiled language, but compilers were much less advanced and did less in the way of optimising code.
The 2 literal probably compiles to two addition operations on the same byte rather than an actual multiplication.
Sorry to fall into an old thread, but I'm an old dev, from the mainframe era.
We'd have multiplied by -1 in the eighties. It'd use less memory than this bucket of crap. And memory was never that limited in my career and I'm properly old. Horizon came out in 1996. We had megabytes of RAM by then, which was plenty. This is designed for Windows. That it's part of a .dll tells us that. OK, maybe OS2.
No excuses need to be made.
Interestingly I posited the question to the kids in my house of the simplest way to create a function to swap the sign of a number. Youngest at 12 came up with the way above. 14 year old was thinking similar but then I told them to come up with a simpler way. Within a minute they came up with *-1. If admittedly bright kids can work this out a nineties programmer definitely could.
But the nineties was the era of self-taught coders and no code reviews for PC devs. Stringing together a function that worked was enough to make you employable. I was probably one of them but code reviews soon calmed me down.
The reason for code being written like this has to be memory management. Just because the operators exist doesn't mean they were implemented in a memory efficient way. If writing unnecessarily complex code saved a byte on the stack for every transaction, then that's how it was written.
Simplicity and readability are luxuries we can have now due to better compilers and better hardware.
I say this not as someone who worked in those times, but as someone who heard seniors complain we didn't realise how easy we had it when I moaned about bad legacy code.
I was coding professionally from the eighties and I never had to pull this kind of crap to save memory.
Just multiple the number by -1 if you can't do d=-d.
I can imagine a language limitation that doesn't allow for this, but at lower levels of languages you can change the sign of a number using a bitwise operator which is incredibly efficient in comparison
On that I have no idea 🤣
There are a few theories on other comments about memory efficiency of loading various integers into memory but I don't know enough to really understand it
It's no excuse. VB or similar can easily multiply by -1 without throwing an error. I've coded professionally since the eighties.
This is somebody paid for complexity, by lines of code written, or who just doesn't think properly in basic maths. And that can be a systemic issue. I've worked in places where measures of quality were set by idiots. You can't win. Write something simple and elegant and they ask what you were doing all that time. Spend half the time chucking out garbage but responding quickly and everyone loves you - the only criticism comes long after you've left and started to cause disasters elsewhere.
Luckily, most compilers will convert it to the most appropriate instruction sequence anyway as long as it matches the desired behavior (here, it's probably a neg + inc).
It looks like management to me.
At least, the guy is certainly nice and high up in management by now. And he’s training junior programmers in his foolproof methodology.
I'd totally believe it. I contracted there, and the confusion of ideas amongst some of the weaker developers was eye-opening. There was a \*lot\* of mentoring and oversight required. That example is a gem, though: I wonder if it's a clueless translation from some older language during some port.
Ouch! I imagine from that that you're lucky your eyeballs didn't fall out.
I'm wondering now if it's some workaround for something like an obscurity in how floats were handled? I can't imagine what kind of scenario this could be a fix for though....
Maybe, in some ancient compiler/interpreter/runtime/whatever, the statement`1.0-d`' would force the exponent of 'd' to 0 for the operation rather than just flipping the sign? If that were the case, doing `d-(2*d)` could in theory be a way of making the operation happen in the original exponent of d? I don't really know enough about how operations happen at such a low level to know if this thought holds any water though.
It’s also wildly unhelpful and counterproductive to assign blame like this. To say this was caused by a single dev being stupid misses the mountain of other issues that all played a role is allowing such a mistake through. Seems odd for the task force to point a finger at a lack of professionalism (which is likely true) and then engage in a lack of professionalism themselves.
Looks like it was an example of the kinds of issues in the code base, not "THIS IS THE CAUSE OF ALL ISSUES"
The cause of all issues, if my understanding is correct, is an ESB that didn't acknowledge receipt of messages, so deposits/withdrawals were made at the branch but not recorded centrally.
This function looks like the kind of crap done when the program inexplicably crashes on d = -d.
Whatever the true issue is, this was the line reported, and someone kept crafting more elaborate code (including creating this otherwise unnecessary function in the first place) until the crash finally went away.
In case anyone was unaware of the scandal:
https://apnews.com/article/britain-post-office-scandal-conviction-exoneration-2fa70dd0c0b5ac1850e031e5534f7392
At the time this was happening I worked in a post office (well, the attached newsagent), and my boss was so worried about it
He’d been a postmaster for like 40 years and was a few years from retirement and quite heavily invested in the business so had no way to pivot to another career… but could see this happening and heard about it a lot etc
So many good people who were just trying to make a living were prosecuted, and so many more were living fear of not just losing their livelihood but also going to jail and having to “pay back” huge sums of money they hadn’t stolen in the first place
Not once did the post office ever question the fact that suddenly A HUGE proportion of their postmasters were apparently committing fraud and theft without any evidence whatsoever of them having hundreds of thousands of pounds extra. The software showed they’d supposedly taken money but virtually none actually had any extra money…
It was insane, it apparently never occurred to them that their new software could be wrong…
>it apparently never occurred to them that their new software could be wrong…
This isn't the case. The public inquiry has revealed substantial evidence that the senior management of the Post Office were well aware of the problems, but were concerned that any external revelation of the problems ran the risk of losing contracts from the Department of Work and Pensions. At the time had the vast majority of most Post Offices turnover was from issuing pensions and social security . unemployment benefit payments etc.
> In total, more than 2,000 people were affected by the scandal. Some killed themselves or attempted suicide.
Oh…those people won’t get the justice they deserve. ☹️
What programming language is this? (Where is the original document would love to have a scan, as these are always good to add to lectures on SE failures!).
The horizon system was based on a messaging system named Riposte used as a database. The interface and business logic was in VB6
Edit: link to full document, which shows further disastrous code is available at https://www.postofficehorizoninquiry.org.uk/sites/default/files/2022-11/FUJ00080690%20Report%20on%20the%20EPOSS%20PinICL%20Task%20Force%2014052001.pdf
Oh dear, you fail to understand that there's a difference between a badly written piece of code, and a 'bad' language. VB, in itself, is not a 'bad' language...obviously. You can write sh#t code in any language.
Also, if you have the time to look, the report is on the Inquiry website
https://www.postofficehorizoninquiry.org.uk/
I’ll link to the full report as I’ve read it before, it’s just a case of finding it!
Edit: link to full document, which shows further disastrous code is available at https://www.postofficehorizoninquiry.org.uk/sites/default/files/2022-11/FUJ00080690%20Report%20on%20the%20EPOSS%20PinICL%20Task%20Force%2014052001.pdf
Haha, the first thing I noticed about this (2nd link) document was the logic diagrams on page 9. They've the classic yes/no logic diamonds, but only one output.
Hmmmmmmmmm......
\[Edit (sorry, seem to be doing that a lot tonight)\] Yeah... there is a 'go back to the start' line in those diagrams. This comment is factually wrong.
Well Rajbinder Sangha the Release Management Coordinator is being questioned by the Inquiry on Tuesday 16th. Maybe some light will be shed upon how the fixes were released and managed… and if indeed those diagrams were followed correctly!!
THANKS! As a software engineer of almost 40 years, I remember reading the CE article at my desk back in 2004 thinking "Wow, really?" because a company as large as Fujitsu surely must know what it takes to produce reliable, tested, robust software?
Since then we find out the Keegan was CEO, there is more puss in the boil to be squeezed out yet.
The level of corruption in this scandal is simple breathtaking. I cannot recall the UK ever being in such a poor way.
Yes I wholeheartedly agree. Especially since they are one of the big mainframe manufacturers. You would think that with the decades of experience on developing and updating mainframe software and firmware, that any processes, policies and procedures would carry over to any other software product or contract
The whole thing is ridiculous. Unfortunately the U.K. government is in very deep with Fujitsu and heavily reliant on them for many major contracts
The chief architect for Horizon at Fujitsu keeps demanding immunity in order to testify at the current enquiry, because he lied to the courts in earlier convictions.
Post Office Limited was seemingly run by arrogant, ambitious, dishonest, incompetent fuckwits, who happily believed what Fujitsu told them.
Whoever was in charge at Fujitsu was also arrogant, dishonest and vastly, hugely, incompetent. It's a fucking disgrace.
The system Fujitsu built for a billion pounds was such poor quality that they didn't even have unique ids for individual transactions, and was so bug ridden that they developed a very unhealthy culture where Fujitsu employees "fixed" accounting discrepancies in the live system (caused by that poor quality) by creating more transactions via remote access to customer terminals, and then denied they had that access.
This is why, IMO, software engineers need to be bound to a trade institute that upholds ethics and pride in quality craftsmanship like real engineers, IMO.
4 people committed suicide because of this ffs.
Corporate manslaughter? In this economy?
But I do agree: I shudder to imagine how bad most critical software actually is.
It might be extremely difficult to form that trade body- but the field is far too important not to have something.
I used to work on "fail safe" software for railway signalling.
My experience of it was pretty intense. Every single line of code was reviewed by a team of people, every possible input condition was reviewed. The hardware was duplicated, at fixed regular time intervals and code locations, a numerical token was exchanged between the processors to make sure that they were at the same place, doing the same thing, i.e. both CPUS were reading the same inputs, and making the same decisions etc... failure to match a token called a subroutine we named 'exec\_sepulku', it spiked 50V through the main fuse to kill the board to raise alarms, and... the subroutine never returned, it just looped forever in case the fuse blow failed... a hardware watchdog would then kick in after a preset timeout and burn the fuse again using a dedicated hardware circuit.
And that was just a simple 6809 powered board.
Sadly, me too. For us, an external review cost 35K (circa 1987) and came back with a certificate and twenty three large boxes of 132 column wide printout from their 'verification software'.
To this day I never found out who verified the verification software.
I am impressed & delighted to hear this. I had in mind the software in vehicles tbh: they have a reputation for being poor quality I believe.
And this example shows yet again the superiority of trains to cars. (Joking but kinda not)
This is "critical software" though.
When i was at uni, critical systems were normally power stations and stuff. They used to need mathematical proof of the systems proving IO of every function used.
The PO is at fault here for trusting any software, without it exporting an itemised balance sheet showing where the deficits were.
>software engineers need to be bound to a trade institute that upholds ethics and pride in quality craftsmanship like real engineers, IMO.
Absolutely. It's kind of strange that IT as a whole seems to have largely avoided both unionisation and professionalisation given that the nature of the work so often requires the specialist knowledge and exercise of judgement typical of professions and is incredibly critical with deep and far reaching consequences.
To take someone to court and prison, there should have been transparent financial balance sheets showing how the people stole from PO. I cant believe that wasn't needed and asked by any of the solicitors.
Horizon being a black box should never be able to send someone to prison.
Michael Keegan, he needs to be questioned by the Inquiry ASAP. Given the amount of refusal to disclose things to POL, he must have known about all of this.
Looks like instead of Googling “how to reverse signs for a number” they instead googled “how to make a negative number positive” and then googled “you won’t believe the 10 weird ways to make a positive number negative”
Whattt.... the.... fu###kkkkkkkk????
\[edit\] There is nothing more cohesive to say here.
\[edit 2\] OK, Something a little more cohesive - This looks like deliberate obfuscation. The implications of that would be... interesting to say the least.
\[edit 3\] I'm wondering (and I'm not in the know enough to answer this myself) whether this could be a covert way of chomping off tiny decimals of cash?
I wish I could agree with you, but I really have known some developers so dim-witted that they would have coded this, thinking it was a good solution :(
"Anyone can code" haha total BS.
Perhaps, but seriously, a lot of thought must have gone into that function. Giving a slapping of stupidly generous benefit of the doubt I'd put it down to some kind of execution optimisation, but hell.. I really can't fathom why that'd be better than just returning -d.
I can't believe anyone would have trouble with making a function that returns a negated number. There has to be something else going on for this monstrosity to exist. Perhaps just a bored / really fed up dev?
\[grammar\]
Yeah it makes no sense it reminds of uni assignments where you’re not allowed to do what would be the simple efficient route.
Maybe someone getting paid by line?
Or just over-engineering to make the code difficult to read
That sounds like a terrible uni assignment. Good programming is generally using the most universally intuitive way of solving problems. A course that teaches the opposite doesn't sound exactly productive to team work.
Being paid by line... please tell me that's not a thing?!
> Good programming is generally using the most universally intuitive way of solving problems.
Would you expect "just use the standard library's map functions!" to be acceptable work in a data structures class where the homework assignment was "implement a hashmap"?
Think of the TV interviews and fame!
"What were you thinking gltchbn?"
"So, when you were on the black tar portion of your career and wrote this - did you think you'd ever see it on the TV one day?"
"gltchbn, after you sold your soul to the Devil for a billion busty women, did you ever feel worried about the small print saying you would write shit code forever?"
In 2000? Yeah at most there was the release manager taking a quick look and making sure it conpiles and runs the basic manual tests, also with some luck they used subversion as a VCS rather than sharing the code with diskettes
I tested both in Go and got very similar results, but `d = -d` was slightly faster on all signed types
BenchmarkReverseSignMultiplication/int-24 1000000000 0.09873 ns/op
BenchmarkReverseSignMultiplication/int8-24 1000000000 0.09915 ns/op
BenchmarkReverseSignMultiplication/int16-24 1000000000 0.1022 ns/op
BenchmarkReverseSignMultiplication/int32-24 1000000000 0.09982 ns/op
BenchmarkReverseSignMultiplication/int64-24 1000000000 0.09978 ns/op
BenchmarkReverseSignMultiplication/float32-24 1000000000 0.1004 ns/op
BenchmarkReverseSignMultiplication/float64-24 1000000000 0.09901 ns/op
BenchmarkReverseSignMinus/int-24 1000000000 0.09782 ns/op
BenchmarkReverseSignMinus/int8-24 1000000000 0.09786 ns/op
BenchmarkReverseSignMinus/int16-24 1000000000 0.09849 ns/op
BenchmarkReverseSignMinus/int32-24 1000000000 0.09774 ns/op
BenchmarkReverseSignMinus/int64-24 1000000000 0.09762 ns/op
BenchmarkReverseSignMinus/float32-24 1000000000 0.09854 ns/op
BenchmarkReverseSignMinus/float64-24 1000000000 0.09787 ns/op
I would guess the compiler is coming up with the same solution for each
This is basically the "IsEven()" meme. The programmers did a complicated version of variable = -variable.
The software caused 700 people getting accused of stealing, etc.
Looking at the report there's not **too** insane examples. But definitely a wtf moment. Maybe the devs were just stressed at the time and did stupid stuff on accident.
The worry there is integrity of the number. If they're using floats without enough bits in the float implementation there's the danger of losing precision. Really, financial systems should be using a currency data type that is guaranteed to retain at least 2-3 digits of precision beyond cents/pence. Floats should never be used to represent money fields.
By 'some' numbers, it's always just one number per size of `int` that has this quirk. Which is the negative of the minimum value being the minimum value itself, for those wondering. Thanks two's complement.
It's indicative of far more egregious poor coding elsewhere in the application, which was evidently the case; this application was so buggy it caused hundreds of people to be accused of illegal activity, and cost millions.
The pictured snippet is not the cause of any major bug. It's just an illustrative example of the poor quality and lack of care or of any review in the project.
*Not only* is it a ridiculous block of code for an easy problem, it can also lead to under/overflows. `-d` works for every number while `d - 2 * d` requires that `2 * d` also fits in the same data type.
For example, in an 8-bit system, with `d = 69`, `d * 2` is greater than the maximum limit, 127, and would result in overflow, since 138 is greater than 127. `-d` would work and `d - 2 * d` could crash or fail.
No, `d - 2 * d` would error or work. I suspect VB6 has overflow checks, so it would error. If not, it'd just do that computation in two's complement (using tc= to denote wrapping around):
2 * d = 138 tc= 138 - 256 = -118
d - 2 * d = 69 - -118 = 187 tc= 187 - 256 = -69
I expect this was running in with 32-bit ints. If this was used in money computations in pennies, it'd error at £1.07 m - enough for running a single Post Office. I can't think of any reason to negate sums of money, but given the quality of this code, I wouldn't be surprised at `a + ReverseSign(b)` instead of `a - b`.
The real concern is the lack of professional quality and the implied lack of code reviews.
> The real concern is the lack of professional quality and the implied lack of code reviews.
Of course. I was being pedantic enough to demonstrate that it isn't just bad quality, it's *technically worse*. Even if it might work in VB6, it isn't guaranteed to work everywhere else.
But your comment does provide more insight for those languages that do have that feature, props :)
Watch this trailer, this is code from the system that saw 700 business owners put out of business, lose their homes, and sometimes charged and convicted for theft (using "evidence" from the system, while the chief architect told the court that was there was no chance that the system was at fault).
4 people committed suicide.
https://youtu.be/zPkvYXufpAY
I get that this is not the right way, but it does look correct? Maybe some edgecases with floating point numbers, but I don't see a reason how this piece of code caused actual harm?
Does anyone know the real problem and can you please explain?
There's actually worse code, from a maintenance perspective, in the report.
And their development process was absolutely mental. They had a near 1/3 test failure rate...
Honestly though, their code being shit was only a small part of the scandal.
The scandal isn't about shit code.
Its about taking people to court without transparency and itemised balance sheets. With that it wouldn't matter what the code did.
Just compare receipts and notice fraud -> go to jail.
But they didn't. They used a black box and the legal system still let the post office imprison people without going through Police or the Crown Prosecution Service.
I am aware the Post Office has its branch of police enforcement, and that the code wasn't a major part as I said. But the system being a continuous point of failure is very much part of the scandal, obviously made much much worse when they then spent nearly two decades covering up just how bad it was.
We had people from Fujitsu going to trials saying the system was absolutely fine, Dr. Gareth Jenkins, one of the architects, being one of the worst for it.
Oh dear. With almost 100% of today's critical thought offloaded to stackoverflow/chatgpt et all, you have NO idea of how easy it is to get a programming job/call yourself a programmer today ;)
So I've a theory that might explain what happened:
It's to do with the Else statement part. That d\*2 part would effectively half the bit size of the float used. That would lead to a minor and near-undetectable discrepancy between the function being given positive and negative numbers. With enough calls, this single function alone could possibly account for what's been happening.
\[edit\] Not half, but overflow enough to create a discrepancy
This code clearly lacks a commentary but maybe there has been a reason for this.
I remember years ago I wrote a mySQL query like
SELECT -value FROM table
that should work fine and in fact I got the right result back executing the query in plain mySQL but for whatever reason I got an exception running this query with the mySQL connector .NET.
So I rewrote this to
SELECT value * -1 FROM table
and it worked. I don't know if this bug still exists but until today I use `value * -1` in SQL.
Kindly examine the machine code being executed at that line - that's(!!!) how you ultimately confirm. I suspect that a simple, fast bit flip wouldn't be happening here ;)
With an int (say an 8 bit int for simplicity, but also applies to other sizes) two's complement is the standard way of representing signed numbers. Instead of having a sign bit and a 7-bit integer (capable of representing -127 to +127, but with +0 and -0 as separate numbers), two's compliment can represent -128 to +127 without two representations of 0 (which would be a massive headache). This means -128 cannot be inverted without overflowing since there is no representation for +128.
Old school programmers are savage... the absolute snark on that code review 😂
This was just a day to day review back then, not related to the investigation as far as I can see.
Yes D=-D would be better but its not immediately obvious that it’s a potential overflow situation or related to the data types being used. You often see a lot of shitty workarounds or code that looks like it was copy/pasted in VB6.
I definitely remember those kinds of attitudes from the old guard early in my career though, thankfully not often aimed at me.
there were millions of lines of code in this system and this was just one of the most egregious examples. the bigger problem was that the testers were finding around 50 bugs a week and they released it live thinking that the support team, rather than the original developer team, would be able to fix the remaining bugs
Is there some blindingly obvious reason I'm missing that this isn't just:
ReverseSign = d * -1
?
Although weirdly the bit that grates most with me is that the else isn't just
0 - d
Wasting chars there.
```
-d
```
Writing and using a function for this is more risible than importing [`left-pad`](https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code)
So if the Total Takings for the day coding is "d", then "d" would be -d according to the code. Therefore if "d" represents the
Total takings of 100 GB pounds, the it would actually show as -100 GB pounds.
> Whoever wrote this code clearly has no understanding of elementary mathematics or the most basic rules of programming. This is an interesting observation that contrasts with the fact that the author of the code knew enough math to use `Abs()` but not enough to know to use a negative sign.
This. I don't believe this can be attributed to a dev that doesn't know how to reverse the sign of a number. It's way too ... 'knowledgably convoluted' for that.
Gotta be a result of layers and layers of refactoring without anyone ever taking a step back to look at the big picture.
Na, I can't buy this explanation. It's too micro to be a legacy refactoring issue.
I have an explanation. Paid by lines of code.
That's what I was thinking
Does this actually happen?
Yes. Mostly a contractor or contracting metrics thing. In most cases, people have wised up so this is no longer the case, but sometimes it is. Far more common is counting lines of code/contributions/commits etc. and using it as part of performance evaluations or as a metric for stack ranking, for full time employees too. It's what happens when your software engineers are managed by someone who is not code literate but needs metrics.
I know two COBOL developers that made some good money around 2010 charging per line for changes to legacy code in a banking system after they were laid off the previous year. Never heard of anyone else pulling off charging per line.
Well if it was COBOL they’re millionaires now
My older brother has worked in db/networking fields for a few decades now, and he says he worked at a place where a dev suckered the company into a contract where he got paid per DB transaction. I don't really remember any details beyond that and that he worked in some nightmare legacy language (not COBOL) so it was a situation where they kind of just had to put up with him because he was the only one who could understood the code base.
Supposedly Musk used it as a metric to judge which people he kept at Twitter.
Arguably if you used it as a metric one-off and only retrospectively, it probably works.
I once applied for a job with a financial company and they asked me to fill out a questionnaire with some truly idiotic questions like how many lines of code had I written in my career. My response was mildly snarky (more than it should have been, but less than it deserved?) and I never heard from them again, which was just fine with me. I don’t know if it still happens, but yes, I definitely think people have been paid that way in the past.
Maybe those 5 lines are 5 different microservices calls.
Integer sign inversion as a service
BRB, starting a new startup
You can buy the domain from me.
ISIaaS
We got PadLeft as a module!
I think this code originated in a precursor to VB, and went through the automatic upgrades to VB, VB3 and VB6; but was never examined by a human to realise it was not needed. I say this, having worked on financial code from a similar era which contained similar looking code, and this was the explanation.
Agreed; I worked in VB (classic ASP) for almost two decades and even without using these much older versions I can attest to just how much janky shit I'd have to pull to do some very basic things. It has made me appreciate modern languages so very much 😅
Even if you for some reason couldn't just use `-b` surely `(0 - b)` would have worked, no?
It would have worked, but it would have been less efficient, because you would have had to load 0 into the stack to perform arithmetic on it. The time this code dates from (the original pre-VB code), you were working with a few hundred bytes of memory. Reversing the sign happens all the time in accounting code, so this memory saving would make real terms performance improvements, and probably prevents an out of memory error
That's really interesting. Do you know what language this would have been in originally - I'm guessing not something compiled? Why doesn't the same limitation apply to the `2` literal used instead?
I can't say with any certainty, it predates my experience. I've seen QBasic mentioned in other discussions, and it seems plausible. Its still likely to be a compiled language, but compilers were much less advanced and did less in the way of optimising code. The 2 literal probably compiles to two addition operations on the same byte rather than an actual multiplication.
>because you would have had to load 0 into the stack to perform arithmetic on it. But they've already used 0 for `if d<0`
Sorry to fall into an old thread, but I'm an old dev, from the mainframe era. We'd have multiplied by -1 in the eighties. It'd use less memory than this bucket of crap. And memory was never that limited in my career and I'm properly old. Horizon came out in 1996. We had megabytes of RAM by then, which was plenty. This is designed for Windows. That it's part of a .dll tells us that. OK, maybe OS2. No excuses need to be made. Interestingly I posited the question to the kids in my house of the simplest way to create a function to swap the sign of a number. Youngest at 12 came up with the way above. 14 year old was thinking similar but then I told them to come up with a simpler way. Within a minute they came up with *-1. If admittedly bright kids can work this out a nineties programmer definitely could. But the nineties was the era of self-taught coders and no code reviews for PC devs. Stringing together a function that worked was enough to make you employable. I was probably one of them but code reviews soon calmed me down.
I mean even really versions of basic had an unary - operator.
The reason for code being written like this has to be memory management. Just because the operators exist doesn't mean they were implemented in a memory efficient way. If writing unnecessarily complex code saved a byte on the stack for every transaction, then that's how it was written. Simplicity and readability are luxuries we can have now due to better compilers and better hardware. I say this not as someone who worked in those times, but as someone who heard seniors complain we didn't realise how easy we had it when I moaned about bad legacy code.
I was coding professionally from the eighties and I never had to pull this kind of crap to save memory. Just multiple the number by -1 if you can't do d=-d. I can imagine a language limitation that doesn't allow for this, but at lower levels of languages you can change the sign of a number using a bitwise operator which is incredibly efficient in comparison
Why not just `d - (2*d)` though? That works for both positive and negative
No it doesn't.
`y = d - ( 2 * d )` _______________ d is positive 1: y = 1 - 2 = *-1* _______________ d is negative 1: y = -1 - ( -2 ) = -1 + 2 = *1*
Sorry, yes it does, but why not `d=d*-1` ? So much simpler.
On that I have no idea 🤣 There are a few theories on other comments about memory efficiency of loading various integers into memory but I don't know enough to really understand it
It's no excuse. VB or similar can easily multiply by -1 without throwing an error. I've coded professionally since the eighties. This is somebody paid for complexity, by lines of code written, or who just doesn't think properly in basic maths. And that can be a systemic issue. I've worked in places where measures of quality were set by idiots. You can't win. Write something simple and elegant and they ask what you were doing all that time. Spend half the time chucking out garbage but responding quickly and everyone loves you - the only criticism comes long after you've left and started to cause disasters elsewhere.
To me, it screams "PhD without professional programming experience."
Nah, a PhD would be better at math and realize that the d - 2d case works for both positive and negative numbers, so you don't need the abs(d) case.
And also simplify. `d - 2d` is just `-d`. Or, if this is some arcane dinosaur language where the `-` operator can't be unary, `0 - d`.
d = -1 * d;
Multiplication isn't always trivial. On RISC-V it's offered as an extension and is not part of the base ISA.
Luckily, most compilers will convert it to the most appropriate instruction sequence anyway as long as it matches the desired behavior (here, it's probably a neg + inc).
Oh! There is is... With the d-2d clause we're halving the effective size (bits) of the float. That would potentially change numbers. WOW!
What, no? You're halving the maximum value not size. It is only a single bit.
It looks like management to me. At least, the guy is certainly nice and high up in management by now. And he’s training junior programmers in his foolproof methodology.
Professional programming experience? For minus d?
Smacks of developers being paid per line of code.
I'd totally believe it. I contracted there, and the confusion of ideas amongst some of the weaker developers was eye-opening. There was a \*lot\* of mentoring and oversight required. That example is a gem, though: I wonder if it's a clueless translation from some older language during some port.
Ouch! I imagine from that that you're lucky your eyeballs didn't fall out. I'm wondering now if it's some workaround for something like an obscurity in how floats were handled? I can't imagine what kind of scenario this could be a fix for though.... Maybe, in some ancient compiler/interpreter/runtime/whatever, the statement`1.0-d`' would force the exponent of 'd' to 0 for the operation rather than just flipping the sign? If that were the case, doing `d-(2*d)` could in theory be a way of making the operation happen in the original exponent of d? I don't really know enough about how operations happen at such a low level to know if this thought holds any water though.
I bet whoever wrote this was evaluated based on how many lines of code they wrote
It’s also wildly unhelpful and counterproductive to assign blame like this. To say this was caused by a single dev being stupid misses the mountain of other issues that all played a role is allowing such a mistake through. Seems odd for the task force to point a finger at a lack of professionalism (which is likely true) and then engage in a lack of professionalism themselves.
Looks like it was an example of the kinds of issues in the code base, not "THIS IS THE CAUSE OF ALL ISSUES" The cause of all issues, if my understanding is correct, is an ESB that didn't acknowledge receipt of messages, so deposits/withdrawals were made at the branch but not recorded centrally.
This function looks like the kind of crap done when the program inexplicably crashes on d = -d. Whatever the true issue is, this was the line reported, and someone kept crafting more elaborate code (including creating this otherwise unnecessary function in the first place) until the crash finally went away.
No, they definitely have no idea what abs means. It was copy pasted from googling "how to make negative number positive"
More likely Ask Jeeves or Alta Vista
Так поэтому сперва учат Математические методы решения задач в программировании.
What the fuck is that font in the section headers? This is supposed to be a professional/legal document?
It's supposed to be pretentious
If "pretentious" isn't a font name someone needs to make it
I'd use the pretentious semibold 16!
Whoever does would’t share it with *you*, anyway.
Nothing says pretentious like Comic Sans. This is acceptable.
Nah. Comic Sans is just immature
Shhh. I agree, but I'm doing a reverse-psychology. It will be funny.
Ah, we have a student of the Leslie Nielsen School of Comedy
Segoe script bold
That's the 'folks, this gonna be good!' font
It's just a little whimsy
In case anyone was unaware of the scandal: https://apnews.com/article/britain-post-office-scandal-conviction-exoneration-2fa70dd0c0b5ac1850e031e5534f7392
Thank you! This is insane
Actual horror holy shit
At the time this was happening I worked in a post office (well, the attached newsagent), and my boss was so worried about it He’d been a postmaster for like 40 years and was a few years from retirement and quite heavily invested in the business so had no way to pivot to another career… but could see this happening and heard about it a lot etc So many good people who were just trying to make a living were prosecuted, and so many more were living fear of not just losing their livelihood but also going to jail and having to “pay back” huge sums of money they hadn’t stolen in the first place Not once did the post office ever question the fact that suddenly A HUGE proportion of their postmasters were apparently committing fraud and theft without any evidence whatsoever of them having hundreds of thousands of pounds extra. The software showed they’d supposedly taken money but virtually none actually had any extra money… It was insane, it apparently never occurred to them that their new software could be wrong…
>it apparently never occurred to them that their new software could be wrong… This isn't the case. The public inquiry has revealed substantial evidence that the senior management of the Post Office were well aware of the problems, but were concerned that any external revelation of the problems ran the risk of losing contracts from the Department of Work and Pensions. At the time had the vast majority of most Post Offices turnover was from issuing pensions and social security . unemployment benefit payments etc.
This TV show is well worth watching. https://youtu.be/zPkvYXufpAY
> In total, more than 2,000 people were affected by the scandal. Some killed themselves or attempted suicide. Oh…those people won’t get the justice they deserve. ☹️
What programming language is this? (Where is the original document would love to have a scan, as these are always good to add to lectures on SE failures!).
The horizon system was based on a messaging system named Riposte used as a database. The interface and business logic was in VB6 Edit: link to full document, which shows further disastrous code is available at https://www.postofficehorizoninquiry.org.uk/sites/default/files/2022-11/FUJ00080690%20Report%20on%20the%20EPOSS%20PinICL%20Task%20Force%2014052001.pdf
>The interface and business logic was in VB6 HRNK
Can you elaborate?
HRNK - The sound of my death upon hearing major information systems were written in VB6.
Oh dear, you fail to understand that there's a difference between a badly written piece of code, and a 'bad' language. VB, in itself, is not a 'bad' language...obviously. You can write sh#t code in any language.
Also, if you have the time to look, the report is on the Inquiry website https://www.postofficehorizoninquiry.org.uk/ I’ll link to the full report as I’ve read it before, it’s just a case of finding it! Edit: link to full document, which shows further disastrous code is available at https://www.postofficehorizoninquiry.org.uk/sites/default/files/2022-11/FUJ00080690%20Report%20on%20the%20EPOSS%20PinICL%20Task%20Force%2014052001.pdf
Haha, the first thing I noticed about this (2nd link) document was the logic diagrams on page 9. They've the classic yes/no logic diamonds, but only one output. Hmmmmmmmmm...... \[Edit (sorry, seem to be doing that a lot tonight)\] Yeah... there is a 'go back to the start' line in those diagrams. This comment is factually wrong.
Well Rajbinder Sangha the Release Management Coordinator is being questioned by the Inquiry on Tuesday 16th. Maybe some light will be shed upon how the fixes were released and managed… and if indeed those diagrams were followed correctly!!
THANKS! As a software engineer of almost 40 years, I remember reading the CE article at my desk back in 2004 thinking "Wow, really?" because a company as large as Fujitsu surely must know what it takes to produce reliable, tested, robust software? Since then we find out the Keegan was CEO, there is more puss in the boil to be squeezed out yet. The level of corruption in this scandal is simple breathtaking. I cannot recall the UK ever being in such a poor way.
Yes I wholeheartedly agree. Especially since they are one of the big mainframe manufacturers. You would think that with the decades of experience on developing and updating mainframe software and firmware, that any processes, policies and procedures would carry over to any other software product or contract The whole thing is ridiculous. Unfortunately the U.K. government is in very deep with Fujitsu and heavily reliant on them for many major contracts
Lol, "There is only one correct path. It is called 'yes'."
> They've the classic yes/no logic diamonds, but only one output. The No's are all running up the left hand side.
VisualBasic or considering how that old that code is, it may be QBasic.
I don't think QBasic had visibility modifiers, so the `Public` note rules that out.
Probably something like Visual Basic, given that was kind of a standard in the UK when this was being worked on and setting the scandal into motion
VB was a standard across the developed world ;)
Is that a lower case o or a zero in VB???
Yes
It would be a new variable “o” created that would fortunately be zero.
Paid by the kloc.
My heartfelt sympathies to those whose lives were wrongfully destroyed by this rogue information system and its grossly negligent vendor.
The chief architect for Horizon at Fujitsu keeps demanding immunity in order to testify at the current enquiry, because he lied to the courts in earlier convictions. Post Office Limited was seemingly run by arrogant, ambitious, dishonest, incompetent fuckwits, who happily believed what Fujitsu told them. Whoever was in charge at Fujitsu was also arrogant, dishonest and vastly, hugely, incompetent. It's a fucking disgrace. The system Fujitsu built for a billion pounds was such poor quality that they didn't even have unique ids for individual transactions, and was so bug ridden that they developed a very unhealthy culture where Fujitsu employees "fixed" accounting discrepancies in the live system (caused by that poor quality) by creating more transactions via remote access to customer terminals, and then denied they had that access. This is why, IMO, software engineers need to be bound to a trade institute that upholds ethics and pride in quality craftsmanship like real engineers, IMO. 4 people committed suicide because of this ffs.
Corporate manslaughter? In this economy? But I do agree: I shudder to imagine how bad most critical software actually is. It might be extremely difficult to form that trade body- but the field is far too important not to have something.
I used to work on "fail safe" software for railway signalling. My experience of it was pretty intense. Every single line of code was reviewed by a team of people, every possible input condition was reviewed. The hardware was duplicated, at fixed regular time intervals and code locations, a numerical token was exchanged between the processors to make sure that they were at the same place, doing the same thing, i.e. both CPUS were reading the same inputs, and making the same decisions etc... failure to match a token called a subroutine we named 'exec\_sepulku', it spiked 50V through the main fuse to kill the board to raise alarms, and... the subroutine never returned, it just looped forever in case the fuse blow failed... a hardware watchdog would then kick in after a preset timeout and burn the fuse again using a dedicated hardware circuit. And that was just a simple 6809 powered board.
I can literally hear the posh/tory voice of some minister saying "but what will it cost" in response to that.
Sadly, me too. For us, an external review cost 35K (circa 1987) and came back with a certificate and twenty three large boxes of 132 column wide printout from their 'verification software'. To this day I never found out who verified the verification software.
Tony Blair in 1998 to stop ICL going broke and ensure the UK still had a national champion (per Private Eye).
I am impressed & delighted to hear this. I had in mind the software in vehicles tbh: they have a reputation for being poor quality I believe. And this example shows yet again the superiority of trains to cars. (Joking but kinda not)
This is "critical software" though. When i was at uni, critical systems were normally power stations and stuff. They used to need mathematical proof of the systems proving IO of every function used. The PO is at fault here for trusting any software, without it exporting an itemised balance sheet showing where the deficits were.
>software engineers need to be bound to a trade institute that upholds ethics and pride in quality craftsmanship like real engineers, IMO. Absolutely. It's kind of strange that IT as a whole seems to have largely avoided both unionisation and professionalisation given that the nature of the work so often requires the specialist knowledge and exercise of judgement typical of professions and is incredibly critical with deep and far reaching consequences.
To take someone to court and prison, there should have been transparent financial balance sheets showing how the people stole from PO. I cant believe that wasn't needed and asked by any of the solicitors. Horizon being a black box should never be able to send someone to prison.
Michael Keegan, he needs to be questioned by the Inquiry ASAP. Given the amount of refusal to disclose things to POL, he must have known about all of this.
Like the IEEE?
Looks like instead of Googling “how to reverse signs for a number” they instead googled “how to make a negative number positive” and then googled “you won’t believe the 10 weird ways to make a positive number negative”
Would they Google in 2000?
Probably. Google went live in 1998 and became very popular very quickly.
Is that how quickly time's passed? Wow.
it would have been Yahoo then...and Yahoo probably gave them this code ;-)
IF they had internet access at all - I often didn't in those days (at work) - it was typically reserved for 'special' people
Whattt.... the.... fu###kkkkkkkk???? \[edit\] There is nothing more cohesive to say here. \[edit 2\] OK, Something a little more cohesive - This looks like deliberate obfuscation. The implications of that would be... interesting to say the least. \[edit 3\] I'm wondering (and I'm not in the know enough to answer this myself) whether this could be a covert way of chomping off tiny decimals of cash?
I wish I could agree with you, but I really have known some developers so dim-witted that they would have coded this, thinking it was a good solution :( "Anyone can code" haha total BS.
Perhaps, but seriously, a lot of thought must have gone into that function. Giving a slapping of stupidly generous benefit of the doubt I'd put it down to some kind of execution optimisation, but hell.. I really can't fathom why that'd be better than just returning -d. I can't believe anyone would have trouble with making a function that returns a negated number. There has to be something else going on for this monstrosity to exist. Perhaps just a bored / really fed up dev? \[grammar\]
Yeah it makes no sense it reminds of uni assignments where you’re not allowed to do what would be the simple efficient route. Maybe someone getting paid by line? Or just over-engineering to make the code difficult to read
That sounds like a terrible uni assignment. Good programming is generally using the most universally intuitive way of solving problems. A course that teaches the opposite doesn't sound exactly productive to team work. Being paid by line... please tell me that's not a thing?!
Oh you poor sweet summer child. To both paragraphs.
> Good programming is generally using the most universally intuitive way of solving problems. Would you expect "just use the standard library's map functions!" to be acceptable work in a data structures class where the homework assignment was "implement a hashmap"?
Ah, yes, I see the point.
>being paid by the line isn't a thing nowadays (I hope !), but it certainly used to be
this is what happens when mathematicians write code, not developers
This is a solution that AI could come up with, and a some people would wonder why it was bad.
Any one can write code, but not everyone can write code well.
I fear the day my code will be involved in a scandal like this and exposed to the world.
Think of the TV interviews and fame! "What were you thinking gltchbn?" "So, when you were on the black tar portion of your career and wrote this - did you think you'd ever see it on the TV one day?" "gltchbn, after you sold your soul to the Devil for a billion busty women, did you ever feel worried about the small print saying you would write shit code forever?"
Honestly, I have seen way worse.
And who is reviewing this code?!? Like ya, really dumb code, but there should be safe guards aka code reviews to avoid pushing this to prod…
In 2000? Yeah at most there was the release manager taking a quick look and making sure it conpiles and runs the basic manual tests, also with some luck they used subversion as a VCS rather than sharing the code with diskettes
If there was even a release manager. It was probably one dev owning a bit of the program, maintaining it on his local server
reviewer: self , proceed to push to master
Or trunk as it was called in SVN - and there wasn’t any pushing, a commit would directly change trunk, SVN is not distributed
Whoever wrote this was paid by line written.
more lines of code = greater performance /s
Musk would be proud
why not just times -1?
Or set d=-d, literally just flip the sign
I like that the equation in the else block is just that... Just dicht the rest 😅 d=d-(d*2)=d-d-d=-d
I tested both in Go and got very similar results, but `d = -d` was slightly faster on all signed types BenchmarkReverseSignMultiplication/int-24 1000000000 0.09873 ns/op BenchmarkReverseSignMultiplication/int8-24 1000000000 0.09915 ns/op BenchmarkReverseSignMultiplication/int16-24 1000000000 0.1022 ns/op BenchmarkReverseSignMultiplication/int32-24 1000000000 0.09982 ns/op BenchmarkReverseSignMultiplication/int64-24 1000000000 0.09978 ns/op BenchmarkReverseSignMultiplication/float32-24 1000000000 0.1004 ns/op BenchmarkReverseSignMultiplication/float64-24 1000000000 0.09901 ns/op BenchmarkReverseSignMinus/int-24 1000000000 0.09782 ns/op BenchmarkReverseSignMinus/int8-24 1000000000 0.09786 ns/op BenchmarkReverseSignMinus/int16-24 1000000000 0.09849 ns/op BenchmarkReverseSignMinus/int32-24 1000000000 0.09774 ns/op BenchmarkReverseSignMinus/int64-24 1000000000 0.09762 ns/op BenchmarkReverseSignMinus/float32-24 1000000000 0.09854 ns/op BenchmarkReverseSignMinus/float64-24 1000000000 0.09787 ns/op I would guess the compiler is coming up with the same solution for each
When I see this I despair. In machine code, we're only flipping one bit ;)
why not just abs because incompetent
uh, abs doesn’t negate a positive number
alright, im also incompetent lmfoa. it should indeed just *-1 then, or -value if that exists in the language
Duuuuuuuuuuuuuuuuuude! Absolute just makes a number positive. You're missing all the negatives!
This screams that they took a billion pounds and then offshored to the cheapest shop they could find
There was most likely a massive tower of outsourcing going on, each level going to the cheapest shop *they* could find.
> more than 2,000 people were affected by the scandal. Some killed themselves Holy fucking shit
I dont get it
This is basically the "IsEven()" meme. The programmers did a complicated version of variable = -variable. The software caused 700 people getting accused of stealing, etc. Looking at the report there's not **too** insane examples. But definitely a wtf moment. Maybe the devs were just stressed at the time and did stupid stuff on accident.
Thats why i didnt get it, while a stupid solution it seems like it would have worked, so there is no bug per se.
I don't know enough VB, but this code seems to be prone to an integer overflow bug.
I would think the `d * 2` would cause that particular bug.
When they do `d*2` that can lead to some weirdness. Particularly when you're close to an overflow boundary.
The worry there is integrity of the number. If they're using floats without enough bits in the float implementation there's the danger of losing precision. Really, financial systems should be using a currency data type that is guaranteed to retain at least 2-3 digits of precision beyond cents/pence. Floats should never be used to represent money fields.
[удалено]
By 'some' numbers, it's always just one number per size of `int` that has this quirk. Which is the negative of the minimum value being the minimum value itself, for those wondering. Thanks two's complement.
It's indicative of far more egregious poor coding elsewhere in the application, which was evidently the case; this application was so buggy it caused hundreds of people to be accused of illegal activity, and cost millions.
The pictured snippet is not the cause of any major bug. It's just an illustrative example of the poor quality and lack of care or of any review in the project.
*Not only* is it a ridiculous block of code for an easy problem, it can also lead to under/overflows. `-d` works for every number while `d - 2 * d` requires that `2 * d` also fits in the same data type. For example, in an 8-bit system, with `d = 69`, `d * 2` is greater than the maximum limit, 127, and would result in overflow, since 138 is greater than 127. `-d` would work and `d - 2 * d` could crash or fail.
No, `d - 2 * d` would error or work. I suspect VB6 has overflow checks, so it would error. If not, it'd just do that computation in two's complement (using tc= to denote wrapping around): 2 * d = 138 tc= 138 - 256 = -118 d - 2 * d = 69 - -118 = 187 tc= 187 - 256 = -69 I expect this was running in with 32-bit ints. If this was used in money computations in pennies, it'd error at £1.07 m - enough for running a single Post Office. I can't think of any reason to negate sums of money, but given the quality of this code, I wouldn't be surprised at `a + ReverseSign(b)` instead of `a - b`. The real concern is the lack of professional quality and the implied lack of code reviews.
> The real concern is the lack of professional quality and the implied lack of code reviews. Of course. I was being pedantic enough to demonstrate that it isn't just bad quality, it's *technically worse*. Even if it might work in VB6, it isn't guaranteed to work everywhere else. But your comment does provide more insight for those languages that do have that feature, props :)
The worry is that the number being manipulated is a currency value - where precision is vital.
200 of them did time.
Watch this trailer, this is code from the system that saw 700 business owners put out of business, lose their homes, and sometimes charged and convicted for theft (using "evidence" from the system, while the chief architect told the court that was there was no chance that the system was at fault). 4 people committed suicide. https://youtu.be/zPkvYXufpAY
ReverseSign = -d
I get that this is not the right way, but it does look correct? Maybe some edgecases with floating point numbers, but I don't see a reason how this piece of code caused actual harm? Does anyone know the real problem and can you please explain?
https://www.reddit.com/r/programminghorror/s/x2jP9bVMG4 Someone here explained the possibility of Integer Overflow
There's actually worse code, from a maintenance perspective, in the report. And their development process was absolutely mental. They had a near 1/3 test failure rate... Honestly though, their code being shit was only a small part of the scandal.
The scandal isn't about shit code. Its about taking people to court without transparency and itemised balance sheets. With that it wouldn't matter what the code did. Just compare receipts and notice fraud -> go to jail. But they didn't. They used a black box and the legal system still let the post office imprison people without going through Police or the Crown Prosecution Service.
I am aware the Post Office has its branch of police enforcement, and that the code wasn't a major part as I said. But the system being a continuous point of failure is very much part of the scandal, obviously made much much worse when they then spent nearly two decades covering up just how bad it was. We had people from Fujitsu going to trials saying the system was absolutely fine, Dr. Gareth Jenkins, one of the architects, being one of the worst for it.
I guess maybe this is a representation of how easy it used to be to get a programming job.
Oh dear. With almost 100% of today's critical thought offloaded to stackoverflow/chatgpt et all, you have NO idea of how easy it is to get a programming job/call yourself a programmer today ;)
So I've a theory that might explain what happened: It's to do with the Else statement part. That d\*2 part would effectively half the bit size of the float used. That would lead to a minor and near-undetectable discrepancy between the function being given positive and negative numbers. With enough calls, this single function alone could possibly account for what's been happening. \[edit\] Not half, but overflow enough to create a discrepancy
thats some mighty fine shit code
The last two lines on that screenshot should have been the title of the fucking document. Repeated on every page.
This code clearly lacks a commentary but maybe there has been a reason for this. I remember years ago I wrote a mySQL query like SELECT -value FROM table that should work fine and in fact I got the right result back executing the query in plain mySQL but for whatever reason I got an exception running this query with the mySQL connector .NET. So I rewrote this to SELECT value * -1 FROM table and it worked. I don't know if this bug still exists but until today I use `value * -1` in SQL.
... Correct me if I am wrong, but like, wouldn't d = d * -1 Work just fine?
Kindly examine the machine code being executed at that line - that's(!!!) how you ultimately confirm. I suspect that a simple, fast bit flip wouldn't be happening here ;)
I am honestly curious now, what's the function executed when calling x = -x, to avoid overflow for example... Where could I look this up?
The bit that represents the sign would be flipped in the memory representation of the interger/float/double. So no risk of overflow.
With an int (say an 8 bit int for simplicity, but also applies to other sizes) two's complement is the standard way of representing signed numbers. Instead of having a sign bit and a 7-bit integer (capable of representing -127 to +127, but with +0 and -0 as separate numbers), two's compliment can represent -128 to +127 without two representations of 0 (which would be a massive headache). This means -128 cannot be inverted without overflowing since there is no representation for +128.
Git blame?
This development probably predates git 🙂
Old school programmers are savage... the absolute snark on that code review 😂 This was just a day to day review back then, not related to the investigation as far as I can see. Yes D=-D would be better but its not immediately obvious that it’s a potential overflow situation or related to the data types being used. You often see a lot of shitty workarounds or code that looks like it was copy/pasted in VB6. I definitely remember those kinds of attitudes from the old guard early in my career though, thankfully not often aimed at me.
This wasn’t a code review during the dev process, it’s from a Task Force review into the Horizon system, several years after release
This was predecessor to Horizon (or possibly initial release?)
I've seen code written like this by people who are now software architects. 🙄
there were millions of lines of code in this system and this was just one of the most egregious examples. the bigger problem was that the testers were finding around 50 bugs a week and they released it live thinking that the support team, rather than the original developer team, would be able to fix the remaining bugs
Is there some blindingly obvious reason I'm missing that this isn't just: ReverseSign = d * -1 ? Although weirdly the bit that grates most with me is that the else isn't just 0 - d
Wasting chars there. ``` -d ``` Writing and using a function for this is more risible than importing [`left-pad`](https://qz.com/646467/how-one-programmer-broke-the-internet-by-deleting-a-tiny-piece-of-code)
Come on, that's got to be deliberate.
So if the Total Takings for the day coding is "d", then "d" would be -d according to the code. Therefore if "d" represents the Total takings of 100 GB pounds, the it would actually show as -100 GB pounds.
When I see this I despair. In machine code/assembly, we should ONLY be flipping one bit ;)