How to flip a Number pos→neg or neg→pos

I had a positive Number variable (the length of a sub-string) that I needed to apply as a negative argument in String.substr(). But, how to flip plus to minus, as there is no operator for this? (as at v9.7.1)

The simple answer, subtract from zero. This works for both attributes and variables of Number type.

var:number vNumber = 5;
vNumber = 0 - vNumber; // vNumber is now -5

You could even make your own function:

function fPosNeg(iNum:number){
   return (0 - iNum);
};
/////
var:number vNumber = fPosNeg(-5);
$Text = vNumber; // $Text shows '5'
vNumber =  fPosNeg(vNumber);
$Text += "\n"+vNumber; // line #2 shows '-5'

Though the function is a little more effort to make (though only one), for me is more intuitive to then use than having to re-remembering “subtract from zero”. For someone with a Maths or code background the subtract-from-zero method might be immediately obvious. Use whichever makes sense!

Edit: also, if you make a function use a name that makes sense to you: my name was done in a rush and perhaps isn’t the best]

Why not use -abs()?

$NewNumber = -abs($OldNumber);

Works for me. Uses less carbon :astonished:

As it happens, there is an operator to do this: unary negate. If $N1 and $N2 are numeric variables, you can write

$N2= - $N1;

Similarly, you can write

$Text="hello "+ (-$N1);

Indeed, but with users from a broad spectrum of fields and expertise (or, pertinently lack of certain expertise) might ‘unary negate’ be a bit recondite? The issue is not wether he method works but whether an ordinary person might know of, or know to ask for such a thing. Knowledge, complete in aggregate, is unevenly distributed amongst us.

The original use case was a bit like this:

var:string vFirstNames = $Name;
if($LastNameSuffix){
	var:number vPart = 0 - $LastNameSuffix.size;
	vFirstNames = $FullName.substr(0, vPart).trim("punctuation");
};
var:string: vName = $LastName;
if($LastNamePrefix){
	vName = $LastNamePrefix+" "+$LastName;
};
var:number vLastLen = 0;
vLastLen = 0 - vName.size; // here is where we need to flip the pos/neg value
vFirstNames = vFirstNames.substr(0, vLastLen);
$AllFirstNames = vFirstNames;

Essentially, this lets me extract “Alfred E.” from “Alfred E. von Neuman, Jr.”. In LaTeX reference typesetting ‘von’, ‘Neuman’ and ‘Jr.’ are all discrete addressable part of what we think of as a name. Yes, but for the love of $deity, why? Oh the joys of academic referencing, making simple stuff gnomic.

.substr(start, len) allows use of a negative len argument to count backwards from the end. I think that part is simple to follow. The hard part becomes, I know what `len’s value is but it’s positive and I need a negative number and there’s no simple [sic] way to do this. The answers above, all valid and well meant, remind us ‘simple’ is in the eye of the beholder.

… I’ll get my coat: it’s the one with the ternary operator description sticking out of the pocket. :slight_smile:

[Edit: this isn’t dissing the ideas above, just explaining why I made the suggestions I did. Sometimes the well-intentioned suggestions shouted from the pier to “swim to the lifebuoy” don’t actually help the blind man who is drowning. We don’t know what we don’t know.]

Might this work?

.substr(start,-len)

The actual code was guarded against start being beyond the end of the string, and against start+len running beyond the end. What I missed was the case where len is negative, and walks back beyond the beginning of the string. Now, that too is guarded.

Oh the joys of academic referencing, making simple stuff gnomic.

Linda. when an undergraduate], had a student conference with a professor who was writing a letter to his colleague, the Marxist historian G. E. M. de Ste. Croix. “How am I to begin?”, he mused. “My dear de Ste. Croix?” “Dear Ste. Croix?” “Croix?”

1 Like

Yes—but only if len can be an attribute or a variable, so it must accept:

.substr(start,-vLength)
.substr(start,-$SomeNumber)

and with/without whitespace around the minus. But, we should recall the real issue is being able, without Maths skillz, simply toggling a number positive/negative, such as might occur in all sorts of contexts. That said, if .sbstr() allowed the above syntax it would resolve the proximate use case.

I think that .substr() does allow for all these possibilities, as should any argument that accepts an expression.

One place it might not work would be a context where Tinderbox cannot know whether the argument is a number:

$MyList=["frogs";"dogs";"oilcans";42];
[String].substr(0,-$MyList[3]);

In this case, I’d suggest storing the list element in a local variable to remind Tinderbox that is is a number.