Chip, the operators #> and <# impose an upper and lower limit (or maybe I have them backwards). The terms min and max imply performing minimum and maximum functions, which is the opposite interpretation. So when you say min you really mean lower limit, and your use of max means upper limit. So why not use opcodes that are more accurate, such as lolim and hilim, or limlo and limhi. Or if you want it shorter, how about llim and hlim, or liml and limh.
Can MIN and MAX still be used as method names if they are operators? I don't think so.
This means you have no chance to make your own MIN, MAX functions that work in the traditional way.
I would just keep the <# and #> operators.
pub min(a,b)
return a #> b
pub max(a,b)
return a <# b
Chip,
For the PASM instructions, literally the opposite names. Given the two operands, MAX currently puts the lower of the two values in D (either moving S to D or leaving D), and that's backwards of what any normal person would expect. Other CPU/MCUs would have MAX "return" the higher of the two inputs, not the lower.
The operation you use for you example is called CLAMP in shaders (GPU stuff) and some extended CPU instructions. It takes 3 operands though. The value to clamp and the min and max range values. Since we don't have 3 operand instructions, it's fine to have it split into 2 instructions. Maybe just rename MAX and MIN to CLAMPU and CLAMPL (for upper and lower). Then we can have an alias of those to be MIN and MAX (but with the opposite of what they are now).
...
In a typical microcontroller app, where most shifts are binary instead of arithmetic, I think it's justifiable to give that task to >>, rather than relegate it to SHR. Anyway, I never saw anything wrong with ~> for SAR (except that I would've used -> or ->> instead, since it has a minus sign as part of the operator).
Anyway, elegance lies in complementary construction. If >> preserves the sign bit, by complementarity, << should also preserve the LSB, right?
-Phil
forget it - shouldn't post before coffee - of course we do not only shift by 1 bit ... in Tachyon we have the shift operators 2* and 2/ which I use and like a lot, makes it very clear what happens
could be written in SPIN as *2 or /2 ???
I always have to look up #> and <# to remember what they mean. Why not something simple like X := LimMax(Y, maxval) or X := LimMax(Y, 100) then you see exactly what the maximum value will be and there is zero confusion about it.
I also had a problem remembering what they meant until I started to think of # as a combination of number and equal symbol. Then x:= #> 0 <# 99 became a number greater than or equal to 0 and less than or equal to 99. Perhaps just a quirk of how my mind works, but it may work for others as well.
...
In a typical microcontroller app, where most shifts are binary instead of arithmetic, I think it's justifiable to give that task to >>, rather than relegate it to SHR. Anyway, I never saw anything wrong with ~> for SAR (except that I would've used -> or ->> instead, since it has a minus sign as part of the operator).
Anyway, elegance lies in complementary construction. If >> preserves the sign bit, by complementarity, << should also preserve the LSB, right?
-Phil
in Tachyon we have the shift operators 2* and 2/ which I use and like a lot, makes it very clear what happens
could be written in SPIN as *2 or /2 ???
The wording of "Ensure x => y" for the MIN operator seems confusing. It sounds like the value of x is changed to equal the value of y if y is greater than x. The description for "x MIN y" should say exactly what it does, which is "returns the maximum value of x and y". And the description of MAX should be "returns the minimum value of x and y". Of course, those accurate descriptions will make the novice programmer wonder why the operator does the opposite of what the name implies, but I think all of us have wondered that ourselves.
EDIT: I would suggest not having aliases for #> and <#, or if you do want to use MIN and MAX for the aliases then swap them so their use is obvious instead of obfuscating the meaning. Of course, if you do that you would probably need to fix the meaning in assembly as well. Maybe better aliases would be CLIPHI and CLIPLO, or CLPH and CLPL. I think it's better to avoid using the terms MIN and MAX because of the misleading connotation of the operators.
Chip, the operators #> and <# impose an upper and lower limit (or maybe I have them backwards). The terms min and max imply performing minimum and maximum functions, which is the opposite interpretation. So when you say min you really mean lower limit, and your use of max means upper limit. So why not use opcodes that are more accurate, such as lolim and hilim, or limlo and limhi. Or if you want it shorter, how about llim and hlim, or liml and limh.
I agree MIN and MAX are now tarnished by historic misuse, so something else is needed in both PASM2 and Spin2.
I was about to argue that MAX, MIN, <# and #> were/are the wrong way around. I put my argument together offline, and in doing so, I realised I had been thinking about this the wrong way.
Here is my explanation why I now think it was/is correct. IMHO, it just needs a better explanation as to why it is so.
We perceive MAX means take the MAXIMUM of two values, and of course MIN means take the MINIMUM of two values.
However, when we look at this from the perspective of placing limits on a value, we have a lower limit (MIN) and an upper limit (MAX).
Mathematically we say MIN <= x <= MAX
Programatically, in spin we could say x := (v1 MIN x) MAX v2 where v1 is the lower limit and v2 is the upper limit.
Thus, MIN will take the greater value of v1 and x,followed by MAX taking the lesser value of the result and v2.
So, in this context, MIN takes the greater value, and MAX takes the lesser value.
This is precisely what we had/have. So, no change necessary!
Cluso,
I just don't agree with changing the meaning of MIN and MAX. Ask any programmer anywhere, and they will say that MAX should give you the maximum of the two values. This is because on other CPUs and in most languages that have MAX, that's what it does.
I'm fine with the #> and <# being how they are, but I strongly think the PASM instructions need a new name that is not MAX or MIN (nor contain them). I like CLAMPU/CLAMPL, or maybe CLAMPGE/CLAMPLE.
Then we can make functions called MIN and MAX that do what is expecting my most everyone.
min/max are not defined in C, but they are defined in C++ STL. std::min and std::max are the normal expected definitions.
Intel added various min/max instructions to the extended instruction (SSE2, SSE4, etc.). MIXSD/MAXSD, MINPD/MAXPD, PMINSD/PMAXSD, etc. These all work as expected. ARM has similar stuff in their NEON extensions (VMIN/VMAX).
That's just two of the most common chips on the planet. I'm sure if I go look I can find more, and they will all work the way I expect them to work. Which is the opposite of what PASM does.
Cluso,
I just don't agree with changing the meaning of MIN and MAX. Ask any programmer anywhere, and they will say that MAX should give you the maximum of the two values. This is because on other CPUs and in most languages that have MAX, that's what it does.
I'm fine with the #> and <# being how they are, but I strongly think the PASM instructions need a new name that is not MAX or MIN (nor contain them). I like CLAMPU/CLAMPL, or maybe CLAMPGE/CLAMPLE.
Then we can make functions called MIN and MAX that do what is expecting my most everyone.
I have to confess, I was caught out enough originally, that I always check the manual for these, both in pasm and spin.
Here are some possible suggestions for naming...
Possible suggestions:
--P1-- -----new suggestions---------------------------------------------------
PASM2:
MAX MIN LOWER LOLIM LIMLO LIMITL LIMITLO LIMMIN CLAMPL CLAMPLE
MAXS MINS LOWERS LOLIMS LIMLOS LIMITLS LIMITLS LIMMINS CLAMPLS CLAMPLS
MIN MAX UPPER HILIM LIMHI LIMITH LIMITHI LIMMAX CLAMPU CLAMPGE
MINS MAXS UPPERS HILIMS LIMHIS LIMITHS LIMITHS LIMMAXS CLAMPUS CLAMPGS
SPIN2:
#> #> LOWERS LOLIMS LIMLOS LIMITLS LIMITLS LIMMINS CLAMPLS CLAMPLS
<# <# UPPERS HILIMS LIMHIS LIMITHS LIMITHS LIMMAXS CLAMPUS CLAMPGS
Once decided, can we back fix (the same into???) P1 PASM1 and SPIN1 ???
Comments
min d,s should give as result the smaller value into d. d=min(d,s).
same goes for max. max d,s should give you the bigger value.
the whole limit thing is complete nonsense.
I do not know of any language besides spin and pasm where max gives you the minimum value and min gives you the maximum value.
it is just wrong.
Mike
This means you have no chance to make your own MIN, MAX functions that work in the traditional way.
I would just keep the <# and #> operators.
Andy
I've seen something like this in C code a lot:
Should be fine to do it this way in Spin also...
For the PASM instructions, literally the opposite names. Given the two operands, MAX currently puts the lower of the two values in D (either moving S to D or leaving D), and that's backwards of what any normal person would expect. Other CPU/MCUs would have MAX "return" the higher of the two inputs, not the lower.
The operation you use for you example is called CLAMP in shaders (GPU stuff) and some extended CPU instructions. It takes 3 operands though. The value to clamp and the min and max range values. Since we don't have 3 operand instructions, it's fine to have it split into 2 instructions. Maybe just rename MAX and MIN to CLAMPU and CLAMPL (for upper and lower). Then we can have an alias of those to be MIN and MAX (but with the opposite of what they are now).
in Tachyon we have the shift operators
2* and 2/ which I use and like a lot, makes it very clear what happens
could be written in SPIN as *2 or /2 ???
I also had a problem remembering what they meant until I started to think of # as a combination of number and equal symbol. Then x:= #> 0 <# 99 became a number greater than or equal to 0 and less than or equal to 99. Perhaps just a quirk of how my mind works, but it may work for others as well.
Kind of makes sense for a single bit shift up or down. Shift up is multiply (*) by 2. Shift down is divide (/) by two.
Except of course shifting right by 1 is not always the same as a divide by 2.
Very confusing.
I agree MIN and MAX are now tarnished by historic misuse, so something else is needed in both PASM2 and Spin2.
Yes, names are better, just avoid ones that have been misused in the past....
The idea is good, but MINS already exists in PASM as backwards, so is best avoided as a 'new' keyword.
What about trying to get closer to the actual operation ?
Along the lines of this : That's easy to read, but strictly applied, does 'above,below' suggests 1001..1999 ?
or Trim Greater or Equal, and Trim Less or Equal
I favour TRIMLE and TRIMGE as you know what the expected result range is from the LE GE
Maybe this also works in PASM2 ?
reads ok to me ?
See above TRIMGE, TRIMLE suggestion. (TRIMSGE, TRIMSLE for signed versions ?, or TRIMUGE, TRIMULE for unsigned )
Sorry, could not resist.
Anyway, that name is already taken for a tool to handle similar chaos in the Javascript language world.
Here is my explanation why I now think it was/is correct. IMHO, it just needs a better explanation as to why it is so.
We perceive MAX means take the MAXIMUM of two values, and of course MIN means take the MINIMUM of two values.
However, when we look at this from the perspective of placing limits on a value, we have a lower limit (MIN) and an upper limit (MAX).
Mathematically we say MIN <= x <= MAX
Programatically, in spin we could say x := (v1 MIN x) MAX v2 where v1 is the lower limit and v2 is the upper limit.
Thus, MIN will take the greater value of v1 and x,followed by MAX taking the lesser value of the result and v2.
So, in this context, MIN takes the greater value, and MAX takes the lesser value.
This is precisely what we had/have. So, no change necessary!
I just don't agree with changing the meaning of MIN and MAX. Ask any programmer anywhere, and they will say that MAX should give you the maximum of the two values. This is because on other CPUs and in most languages that have MAX, that's what it does.
I'm fine with the #> and <# being how they are, but I strongly think the PASM instructions need a new name that is not MAX or MIN (nor contain them). I like CLAMPU/CLAMPL, or maybe CLAMPGE/CLAMPLE.
Then we can make functions called MIN and MAX that do what is expecting my most everyone.
-Phil
Yes, I think I previously asked this question about PASM 2
This is getting out of hand.
Not sure how to rename the PASM mnemonics.
There is no MIN or MAX defined in C.
Or did I miss the memo?
I figured MIN (,) and MAX (,) were common C functions. I figured that must be where these notions came from.
I can't think it through now but the simplistic macros David presents are full of problems when used with different types.
Linus Torvalds made a bit of a storm about this when min/max was used badly in his kernel some years ago. The end result is this (from /kernel.h):
Thanks! Don't care if PASM is weird, but let people define MAX and MIN in Spin as we want...
-Phil
How about these mnemonics:
MINU, MAXU for unsigned version
MINS, MAXS for the signed version
So min and max are no longer reserved words, and the menmonics do not look like min(,) max(,) macros in C.
Andy
Intel added various min/max instructions to the extended instruction (SSE2, SSE4, etc.). MIXSD/MAXSD, MINPD/MAXPD, PMINSD/PMAXSD, etc. These all work as expected. ARM has similar stuff in their NEON extensions (VMIN/VMAX).
That's just two of the most common chips on the planet. I'm sure if I go look I can find more, and they will all work the way I expect them to work. Which is the opposite of what PASM does.
Here are some possible suggestions for naming...
Once decided, can we back fix (the same into???) P1 PASM1 and SPIN1 ???
Well, why not, Intel has been adding a few new instructions every month for three decades now!