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
Soricidus
Oct 21, 2010
freedom-hating statist shill

canis minor posted:

Taken from SO

code:
function round(num) {
    return +(Math.round(num + "e+2") + "e-2");
}
it works, but it makes my skin crawl

for values of "works" that include "sometimes returns NaN because stringifying a number might already include an exponent bit"

Adbot
ADBOT LOVES YOU

qntm
Jun 17, 2009
Yeah, and what if num is an object?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
so that was written because Javascript doesn't have a standard library round() that offers a "number of decimal places" optional parameter, I guess??? I mean that's the only way I can make sense of it.

qntm
Jun 17, 2009
JavaScript has this, but it returns a string, presumably under the assumption that the only time you would voluntarily sacrifice decimal places is at output time?

tyrelhill
Jul 30, 2006
Plus some people think their lovely code golf solutions are super cool and jee golly

eth0.n
Jun 1, 2012

qntm posted:

JavaScript has this, but it returns a string, presumably under the assumption that the only time you would voluntarily sacrifice decimal places is at output time?

If your round function supports decimal places, and returns a double, then for a lot of inputs, you end up with a value that isn't actually a value rounded to that number of decimal places, since it can't be represented exactly. There isn't much use for that. Rounding is usually for display, and if you print that double, you might not get what you expect.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
I use round a lot in shaders, since it's the best way I've found to discretise colour values if I need to. I.e. colour values range [0;1] so to discretise into x steps I do round(x*color)/x. Not that it's complicated enough to need its own function at all, but it does have its uses.

Sedro
Dec 31, 2008

Joda posted:

I use round a lot in shaders, since it's the best way I've found to discretise colour values if I need to. I.e. colour values range [0;1] so to discretise into x steps I do round(x*color)/x. Not that it's complicated enough to need its own function at all, but it does have its uses.

Not enough to warrant a function? Oh, there's an npm package for that

https://www.npmjs.com/package/round-to

vOv
Feb 8, 2014

And look how it's implemented!

code:
	var exponent = precision > 0 ? 'e' : 'e-';
	var exponentNeg = precision > 0 ? 'e-' : 'e';
	precision = Math.abs(precision);

	return Number(Math[fn](x + exponent + precision) + exponentNeg + precision);

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

leper khan posted:

Every day I run into some thing that unity-C# doesn't let me do that was added in .Net4. Like combining more than two portions of a path at once (this mornings slap in the face; I'm sure I've run into it before but lomarf if I'll remember everything that was added in .Net4 [or .Net3.5 that isn't included in unity's insane cross compiler thing]).

Someone remind me why everyone seems to use this garbage fire of a game engine and why I can never have nice things.

Because Unity are a bunch of cheap jerks who forked a really old version of the mono compiler and didn't want to pay Xamarin one red cent for a compiler and runtime that were actually updated. So they kept hacking on their old version forever, resulting in worse performance, worse battery life, and lack of modern C# features.

Now that Microsoft bought Xamarin and open-sourced the whole drat thing you might think they'd adopt it but last I heard their unique snowflake codebase may have diverged too much.

tl;dr: Game developers are the worst.

xtal
Jan 9, 2011

by Fluffdaddy

Joda posted:

I use round a lot in shaders, since it's the best way I've found to discretise colour values if I need to. I.e. colour values range [0;1] so to discretise into x steps I do round(x*color)/x. Not that it's complicated enough to need its own function at all, but it does have its uses.

You don't create functions because they're complicated, you create functions to remove duplication

vOv posted:

And look how it's implemented!

code:
	var exponent = precision > 0 ? 'e' : 'e-';
	var exponentNeg = precision > 0 ? 'e-' : 'e';
	precision = Math.abs(precision);

	return Number(Math[fn](x + exponent + precision) + exponentNeg + precision);

We should have expected this

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

xtal posted:

You don't create functions because they're complicated, you create functions to remove duplication


We should have expected this

You create functions to express the concept of doing something. There are many pleasant effects to explicitly expressing that a certain code sequence represents a discrete thing, avoiding code duplication being one. But also it makes it much easier to focus on the problem at hand when you are working on complicated code. Also, each function should do one thing, and that thing should be at the level of abstraction suggested by its name. DisplayMainWindow() shouldn't contain any code about implementing a custom dashboard widget, for example, even though such code could conceivably be used only on this one window and will have to run in order to accomplish the task.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

xtal posted:

You don't create functions because they're complicated, you create functions to remove duplication

The main purpose of functions is to improve clarity of code. De-duplication is a side effect of that.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

pokeyman posted:

Like documentation, or planning, or specification.

(As I list the ways that typographically correct quotation marks have entered my code.)

(Which was caught immediately by the compiler.)

You can disable autocorrect and spellcheck for individual Word paragraph styles :eng101: ([ASK] me about writing my undergrad thesis in Word)

Munkeymon
Aug 14, 2003

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



hackbunny posted:

You can disable autocorrect and spellcheck for individual Word paragraph styles :eng101: ([ASK] me about writing my undergrad thesis in Word)

:catstare:

Did you wear a nail belt and sackcloth the whole time, too?

FlapYoJacks
Feb 12, 2009
Let me tell you of a kernel horror that caused me three weeks of frustration.

I am doing board bring up and we are using a tas2552 8ohm amplifier on this board. For weeks I have been troubleshooting this thing trying to figure out why sound wasn't working despite every i2s clock line looking perfect.

The issue was i2c. But i2c I thought was working because I could read registers from the chip!

WRONG. I only thought I could, because the sound_soc_write function not only tries to write to the chip via i2c, but also updates a local array of values stored in the driver via a regmap array.

So the driver would write but didn't check the return value which was -EIO every single time.
The driver also never checked the version register.

What's worse though, is that sound_soc_read doesn't ask the chip for the register value. It just reads the value from the regmap array that sound_soc_write stored! So for WEEKS I thought i2c was working when it wasn't.

God drat it!

FlapYoJacks fucked around with this message at 12:41 on Oct 26, 2016

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

ratbert90 posted:

Let me tell you of a kernel horror that caused me three weeks of frustration.

I am doing board bring up and we are using a tas2552 8ohm amplifier on this board. For weeks I have been troubleshooting this thing trying to figure out why sound wasn't working despite every i2s clock line looking perfect.

The issue was i2c. But i2c I thought was working because I could read registers from the chip!

WRONG. I only thought I could, because the sound_soc_write function not only tries to write to the chip via its, but also updates a local array of values stored in the driver via a regmap array.

So the driver would write but didn't check the return value which was -EIO every single time.
The driver also never checked the version register.

What's worse though, is that sound_soc_read doesn't ask the chip for the register value. It just reads the value from the regmap array that sound_soc_write stored! So for WEEKS I thought i2c was working when it wasn't.

God drat it!

Hardware people are the worst.

vOv
Feb 8, 2014

ratbert90 posted:

Let me tell you of a kernel horror that caused me three weeks of frustration.

I am doing board bring up and we are using a tas2552 8ohm amplifier on this board. For weeks I have been troubleshooting this thing trying to figure out why sound wasn't working despite every i2s clock line looking perfect.

The issue was i2c. But i2c I thought was working because I could read registers from the chip!

WRONG. I only thought I could, because the sound_soc_write function not only tries to write to the chip via its, but also updates a local array of values stored in the driver via a regmap array.

So the driver would write but didn't check the return value which was -EIO every single time.
The driver also never checked the version register.

What's worse though, is that sound_soc_read doesn't ask the chip for the register value. It just reads the value from the regmap array that sound_soc_write stored! So for WEEKS I thought i2c was working when it wasn't.

God drat it!

I don't speak hardware, so let me see if I understand this correctly: sound_soc_write both actually writes the value to wherever without checking whether the write succeeded, but also stores the written value in a cache memory, and sound_soc_read just reads from the cache without ever touching the actual chip? That's loving fantastic.

Hammerite
Mar 9, 2007

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

ratbert90 posted:

Let me tell you of a kernel horror that caused me three weeks of frustration.

I am doing board bring up and we are using a tas2552 8ohm amplifier on this board. For weeks I have been troubleshooting this thing trying to figure out why sound wasn't working despite every i2s clock line looking perfect.

The issue was i2c. But i2c I thought was working because I could read registers from the chip!

WRONG. I only thought I could, because the sound_soc_write function not only tries to write to the chip via its, but also updates a local array of values stored in the driver via a regmap array.

So the driver would write but didn't check the return value which was -EIO every single time.
The driver also never checked the version register.

What's worse though, is that sound_soc_read doesn't ask the chip for the register value. It just reads the value from the regmap array that sound_soc_write stored! So for WEEKS I thought i2c was working when it wasn't.

God drat it!

I would be spitting fire and looking for people's heads at that point

FlapYoJacks
Feb 12, 2009

Simulated posted:

Hardware people are the worst.

I'm a hardware guy, just not poo poo at checking return values. :colbert:

vOv posted:

I don't speak hardware, so let me see if I understand this correctly: sound_soc_write both actually writes the value to wherever without checking whether the write succeeded, but also stores the written value in a cache memory, and sound_soc_read just reads from the cache without ever touching the actual chip? That's loving fantastic.

Almost! Let me take you down a magical journey!

Here's the C file for anybody who want's to play along:
http://lxr.free-electrons.com/source/sound/soc/codecs/tas2552.c


On line 41 you have struct reg_default tas2552_reg_defs[] which is used as part of a overall larger struct called regmap_config on line 678.

tas2552_reg_defs[] should be set to DEFAULT REGISTER VALUES

On line 707 this struct is passed to devm_regmap_init_i2c, which calls regmap_get_i2c_bus (this passes because there are 2 other chips working on the same i2c line), and devm_regmap_init.

devm_regmap_init calls regmap_init which then puts the register map into sysfs. This is actually very useful for debugging.

At this point, no registers have been written, as they are supposedly DEFAULT VALUES.


So here is where things get hosed up.

The first time a write to the chip supposedly occurs is on line 595. The function snd_soc_update_bits returns 0 on success, or a negative error code otherwise. Now what happens here is this logic:

C code:
int snd_soc_component_update_bits(struct snd_soc_component *component,
	unsigned int reg, unsigned int mask, unsigned int val)
{
	bool change;
	int ret;

	if (component->regmap)
		ret = regmap_update_bits_check(component->regmap, reg, mask,
			val, &change);
	else
		ret = snd_soc_component_update_bits_legacy(component, reg,
			mask, val, &change);

	if (ret < 0)
		return ret;
	return change;
}
Oh look, if you have a regmap then regmap_update_bits_check is called, which to be fair to this function does fail and does return a negative error number, however the driver code itself does not check anywhere the return value and goes on it's merry way like nothing bad ever happened. This isn't the real horror though. Sure it's bad, but not the real travisty of the story.

The real problem is when sound_soc_read is called. This is where things get hosed up. snd_soc_read calls snd_soc_component_read which has this logic:

code:
int snd_soc_component_read(struct snd_soc_component *component,
	unsigned int reg, unsigned int *val)
{
	int ret;

	if (component->regmap)
		ret = regmap_read(component->regmap, reg, val);
	else if (component->read)
		ret = component->read(component, reg, val);
	else
		ret = -EIO;

	return ret;
}
regmap_read calls _regmap_read which has this logic in it:

code:
static int _regmap_read(struct regmap *map, unsigned int reg,
			unsigned int *val)
{
	int ret;
	void *context = _regmap_map_get_context(map);

	WARN_ON(!map->reg_read);

	if (!map->cache_bypass) {
		ret = regcache_read(map, reg, val);
		if (ret == 0)
			return 0;
	}

	if (map->cache_only)
		return -EBUSY;

	if (!regmap_readable(map, reg))
		return -EIO;

	ret = map->reg_read(context, reg, val);
	if (ret == 0) {
#ifdef LOG_DEVICE
		if (map->dev && strcmp(dev_name(map->dev), LOG_DEVICE) == 0)
			dev_info(map->dev, "%x => %x\n", reg, *val);
#endif

		trace_regmap_reg_read(map, reg, *val);

		if (!map->cache_bypass)
			regcache_write(map, reg, *val);
	}

	return ret;
}
And there's the problem. If you don't set cache_bypass as a flag (which is NOT THE DEFAULT) it reads FROM THE MODIFIED ARRAY AND NOT THE loving CHIP.

At this point you get a success on return, and it creates a perfect loving storm of making it look like i2c is working.

Three weeks. I will never EVER trust wrappers around read/writes again.

necrobobsledder
Mar 21, 2005
Lay down your soul to the gods rock 'n roll
Nap Ghost
Bad software being so common and written by people that never wanted to write software (most EEs) is why I left embedded software. Thanks for the reminder.

Volte
Oct 4, 2004

woosh woosh
Electricity doesn't have return values other than "ok" and "smoke"

xtal
Jan 9, 2011

by Fluffdaddy
And sometimes the smoke is also ok

TooMuchAbstraction
Oct 14, 2012

I spent four years making
Waves of Steel
Hell yes I'm going to turn my avatar into an ad for it.
Fun Shoe
Also, while I don't know about what sounds like a pretty low-level hardware control system, it's super-common for high-level stuff to use a cache for most reads, because communicating with hardware is super slow and most of the time you don't expect values to have changed.

I mean, the "should I use a cache?" setting should be a parameter to the read method, instead of a property of some object, and caches might well not actually be appropriate in this case, and the cache should be invalidated after any write...

FlapYoJacks
Feb 12, 2009

TooMuchAbstraction posted:

Also, while I don't know about what sounds like a pretty low-level hardware control system, it's super-common for high-level stuff to use a cache for most reads, because communicating with hardware is super slow and most of the time you don't expect values to have changed.

I mean, the "should I use a cache?" setting should be a parameter to the read method, instead of a property of some object, and caches might well not actually be appropriate in this case, and the cache should be invalidated after any write...

The cache is fine because it's used in conjunction with the chip being in power savings mode. That way you can write values and then chip get's them once it comes back online.

The real horror was not checking the return values of the writes.


Also:

Once I got i2c working (added resistor to ground messed with the address pad), sound instantly worked. I am going to submit a patch to the kernel that checks the version register on probe.

csammis
Aug 26, 2003

Mental Institution
Let's not miss the horror where the cache was being updated with written values despite the hardware write apparently failing


e: fb

nielsm
Jun 1, 2009



Volte posted:

Electricity doesn't have return values other than "ok" and "smoke"

What's the failure mode of a smoke machine?

Carbon dioxide
Oct 9, 2012

Volte
Oct 4, 2004

woosh woosh
God I miss XML

Klades
Sep 8, 2011

nielsm posted:

What's the failure mode of a smoke machine?

As a former Chuck E. Cheese technician, I am qualified to answer this.
The failure mode of a smoke machine is "fire".

Some people might claim that "no smoke" is a failure mode, but at CEC if it's not on fire it's not broken enough to replace.

Soricidus
Oct 21, 2010
freedom-hating statist shill

Volte posted:

God I miss XML

I don't





(because i'm still using it. bad luck if you're not)

nielsm
Jun 1, 2009




So what you're saying that we should actually praise PHP for having one of the best JSON parsers out there.

Soricidus
Oct 21, 2010
freedom-hating statist shill
My toilet is really good at emptying its bowl. It's still a toilet and the stuff that goes in the bowl is still poo poo.

Volte
Oct 4, 2004

woosh woosh
That test suite has an error actually, the row that almost every language fails is not an error.

RFC 7159 posted:

Implementations MUST NOT add a byte order mark to the beginning of a
JSON text. In the interests of interoperability, implementations
that parse JSON texts MAY ignore the presence of a byte order mark
rather than treating it as an error.

Beef
Jul 26, 2004
If history is anything to go by, people will use this to justify a replacement that is somehow even worse.

xzzy
Mar 5, 2009

As long as javascript remains a dominant player json ain't going anywhere.

Volguus
Mar 3, 2009

xzzy posted:

As long as javascript remains a dominant player json ain't going anywhere.

Isn't this more about how garbage the parsers are and less about how lovely json itself is? While I haven't read the RFC, in common usage json doesn't come as being inherently flawed, unlike yaml, where the tiniest mistake (wrong space or tab) breaks the entire thing.

And about JS: are the existing JS engines so performant that nobody wants to replace them? Even chrome doesn't come with a native Dart engine (it did in a developer edition). Or Edge with Typescript. Everyone just compiles to JS, like is the holy loving grail of languages.

xzzy
Mar 5, 2009

Volguus posted:

Isn't this more about how garbage the parsers are and less about how lovely json itself is?

Of course, I was just replying to Beef's post about the inevitability of a json replacement. Sure it's gonna happen, and it already has. But javascript has so much of the momentum right now json will be a thing for a while longer.

The piss poor quality of the parsers is pretty much business as usual in the computing world. The lesson there seems to be "simple data only, you don't need all that fancy unicode anyways."

Su-Su-Sudoko
Oct 25, 2007

what stands in the way becomes the way

Volguus posted:

And about JS: are the existing JS engines so performant that nobody wants to replace them? Even chrome doesn't come with a native Dart engine (it did in a developer edition). Or Edge with Typescript. Everyone just compiles to JS, like is the holy loving grail of languages.

webassembly might change this

Adbot
ADBOT LOVES YOU

Volte
Oct 4, 2004

woosh woosh
If I ever consider using JSON for cross-server interop I just imagine trying to send a date from Javascript to Python reliably and my brain kind of short circuits and resets.

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