Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
August 02, 2006 There must be a better way | ||||
---|---|---|---|---|
| ||||
I wrap two values (x && y coordinates) like this: uint wrap(uint axis, int value) { int max=0; if (axis==1) max=25; if (axis==0) max=10; if(value>=max){ return (value % max); } if(value<0){ int newValue; newValue=value; while(newValue<0){ newValue+=max; } return (newValue); } return value; } So I need to do things like 'wrap(0,currentX)' everytime to wrap the currentX. Like: (the original x && y need to be untouched) array[wrap(0,currentX)][wrap(1,currentY)]; Is this really the best way, or am I just missing some nifty D programming? Two small questions: 1. Isn't inout more used than out for functions, in contrast to what the website says? I use inout quite often, or am I just doing something wrong? 2. Is it really difficult to make '>=" correctly compare an unsigned and a signed int? (This took me some time to find out :) Grtz, Emp |
August 02, 2006 Re: There must be a better way | ||||
---|---|---|---|---|
| ||||
Posted in reply to Emp | On Wed, 2 Aug 2006 03:57:07 +0200, Emp wrote: > I wrap two values (x && y coordinates) like this: > > uint wrap(uint axis, int value) > { > int max=0; > if (axis==1) max=25; > if (axis==0) max=10; > if(value>=max){ > return (value % max); > } > if(value<0){ > int newValue; > newValue=value; > while(newValue<0){ > newValue+=max; > } > return (newValue); > } > return value; > } > > So I need to do things like 'wrap(0,currentX)' everytime to wrap the > currentX. Like: > > (the original x && y need to be untouched) > array[wrap(0,currentX)][wrap(1,currentY)]; > > Is this really the best way, or am I just missing some nifty D programming? Here is an alternative... const AXIS0 = 10; const AXIS1 = 25; int mwrap(int max, int value) { if(value >= max) { value %= max; } else if (value < 0) { value = max + (value % max); if (value == max) value = 0; } return value; } unittest { assert(mwrap(AXIS0, 35) == 5); assert(mwrap(AXIS0, 0) == 0); assert(mwrap(AXIS0, 6) == 6); assert(mwrap(AXIS0, 10) == 0); assert(mwrap(AXIS1, 35) == 10); assert(mwrap(AXIS1, 0) == 0); assert(mwrap(AXIS1, 6) == 6); assert(mwrap(AXIS1, 25) == 0); assert(mwrap(AXIS0, -35) == 5); assert(mwrap(AXIS0, -6) == 4); assert(mwrap(AXIS0, -10) == 0); assert(mwrap(AXIS1, -35) == 15); assert(mwrap(AXIS1, -6) == 19); assert(mwrap(AXIS1, -25) == 0); } The main change I made was to supply the actual maximum value as a parameter. This will make the function more flexible in future. The other change was to not a D trick, just a maths 'trick'. > Two small questions: > 1. Isn't inout more used than out for functions, in contrast to what the > website says? > I use inout quite often, or am I just doing something wrong? Yes, IMHO <g> The use of return values rather than updating the input parameters leads to programs that are easier to maintain and re-use. > 2. Is it really difficult to make '>=" correctly compare an unsigned and a signed int? No. This is huge wart in D. For some Bob-only-knows reason, D silently interprets the bit-value of an int as if was a uint when doing such comparisons. Daft! If you know that there is not going to be an overflow issue, you can do this ... if (cast(int)my_uint >= my_int) ... which is saying you want the uint converted to a signed value before comparing the two. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 2/08/2006 12:41:01 PM |
August 02, 2006 Re: There must be a better way | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Thanks for the maths :) The maximum are not constant and writing out the place they live would yield to something like: array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)]; So the int was a bit of a hack... sorry :) About the inout: How would you do something like this? bool something(inout structure struc ,int var){ for (int i=0; i < struc.data[].length; i++){ if(struc.data[i].count==0){ struc.data[i].type=var; struc.data[i].count=30; return true; } } return false; } |
August 02, 2006 Re: There must be a better way | ||||
---|---|---|---|---|
| ||||
Posted in reply to Emp | On Wed, 2 Aug 2006 05:49:44 +0200, Emp wrote: > About the inout: > How would you do something like this? > > bool something(inout structure struc ,int var){ > for (int i=0; i < struc.data[].length; i++){ > if(struc.data[i].count==0){ > struc.data[i].type=var; > struc.data[i].count=30; > return true; > } > } > return false; > } Ah yes... the problem with structs. The way you have done it here is a trade-off for performance and works fine. The alternative would be to pass back and forth the complete structure which is not a generally a good idea. You could make it a class instead of a structure but that would be just pedantic ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 2/08/2006 2:39:58 PM |
August 02, 2006 Re: There must be a better way | ||||
---|---|---|---|---|
| ||||
Posted in reply to Emp | I'm not clear on where your going, but I like to keep things simpler and thus more maintainable. Instead of: array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)]; I would probably prefer... whatever_t getWrapped(whatever_t[][] array, int x, int y, int var) { return array[wrap(something[var].maxX, x)][wrap(something[var].maxY, y)]; } Then you'd do: array.getWrapped(currentX, currentY, var); Which would seem much easier, and should be optimized out the same with inlining. But this might not be practical depending on what "something" is (I'm guessing here it's a lookup or something.) Also, fwiw, I use inout all the time. I think there are specific design patterns and code paths with which it makes complete sense. Example: // Attempt to bring item to the top/head of the linked list. if (!bringToTop(linked_list, item)) writefln("Uh oh, %s was not found!", item.toString()); I don't think it's ambiguous that linked_list might be modified. Just my opinion. I might prefer "linked_list.bringToTop(item)" if it made sense, though (since that's even harder to misunderstand.) -[Unknown] > Thanks for the maths :) > The maximum are not constant and writing out the place they live would yield to something like: > > array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)]; > > So the int was a bit of a hack... sorry :) > > About the inout: > How would you do something like this? > > bool something(inout structure struc ,int var){ > for (int i=0; i < struc.data[].length; i++){ > if(struc.data[i].count==0){ > struc.data[i].type=var; > struc.data[i].count=30; > return true; > } > } > return false; > } > > > > > > > |
August 04, 2006 Re: There must be a better way | ||||
---|---|---|---|---|
| ||||
Posted in reply to Unknown W. Brackets | I've been looking through your post but kind quite grasp how I should prog like that... :/ I want to do stuff like this: (I hope it is a bit more clear) type=block.data[wrap(0,x)][wrap(1,y)].type; with: uint wrap(uint axis, int value) { int max=1; if (axis==1) max=block.maxX; //variable if (axis==0) max=block.maxY; //same :) if(value >= max){ value %= max; }else if (value < 0){ value = max + (value % max); if (value == max) value = 0; } return value; } > I'm not clear on where your going, but I like to keep things simpler and thus more maintainable. Instead of: > > array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)]; > > I would probably prefer... > > whatever_t getWrapped(whatever_t[][] array, int x, int y, int var) > { > return array[wrap(something[var].maxX, x)][wrap(something[var].maxY, y)]; > } > > Then you'd do: > > array.getWrapped(currentX, currentY, var); > > Which would seem much easier, and should be optimized out the same with inlining. But this might not be practical depending on what "something" is (I'm guessing here it's a lookup or something.) > > Also, fwiw, I use inout all the time. I think there are specific design patterns and code paths with which it makes complete sense. Example: > > // Attempt to bring item to the top/head of the linked list. > if (!bringToTop(linked_list, item)) > writefln("Uh oh, %s was not found!", item.toString()); > > I don't think it's ambiguous that linked_list might be modified. Just my opinion. I might prefer "linked_list.bringToTop(item)" if it made sense, though (since that's even harder to misunderstand.) > > -[Unknown] > > >> Thanks for the maths :) >> The maximum are not constant and writing out the place they live would >> yield to something like: >> >> array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)]; >> >> So the int was a bit of a hack... sorry :) >> >> About the inout: >> How would you do something like this? >> >> bool something(inout structure struc ,int var){ >> for (int i=0; i < struc.data[].length; i++){ >> if(struc.data[i].count==0){ >> struc.data[i].type=var; >> struc.data[i].count=30; >> return true; >> } >> } >> return false; >> } >> >> >> >> >> >> |
August 04, 2006 Re: There must be a better way | ||||
---|---|---|---|---|
| ||||
Posted in reply to Emp | I guess, then, you'd have block with data inside it, as you do now, but data would have to be a class. It would have to know about its parent, block.
Then you would be able to do something like that.
However, if you can settle for:
type = block.data(wrap(0, x), wrap(1, y)).type;
Then you don't need a class to proxy things. But, is the call to wrap mandatory? It looks like you really want something like below...
Let me note that D, when it sees this:
x.y(z);
Will try:
y(x, z);
If the function is available. That's what I'm using (abusing?) here.
data_t data(whatever_block_is_t block, uint x, uint y)
{
return return block.realData[wrap(x, block.maxX)][wrap(y, block.maxY)];
}
uint wrap(uint value, uint max)
{
if (value >= max)
return value % max;
else if (value < 0)
return max + (value % max);
else
return value;
}
So then you'd do:
type = block.data(x, y).type;
Assuming you always want the x and why wrapped. If you didn't, you could still do:
type = block.realData[x][y].type;
-[Unknown]
> I've been looking through your post but kind quite grasp how I should prog like that... :/
> I want to do stuff like this:
> (I hope it is a bit more clear)
>
> type=block.data[wrap(0,x)][wrap(1,y)].type;
>
> with:
> uint wrap(uint axis, int value)
> {
> int max=1;
> if (axis==1) max=block.maxX; //variable
> if (axis==0) max=block.maxY; //same :)
>
> if(value >= max){
> value %= max;
> }else if (value < 0){
> value = max + (value % max);
> if (value == max) value = 0;
> }
>
> return value;
> }
>
>> I'm not clear on where your going, but I like to keep things simpler and thus more maintainable. Instead of:
>>
>> array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)];
>>
>> I would probably prefer...
>>
>> whatever_t getWrapped(whatever_t[][] array, int x, int y, int var)
>> {
>> return array[wrap(something[var].maxX, x)][wrap(something[var].maxY, y)];
>> }
>>
>> Then you'd do:
>>
>> array.getWrapped(currentX, currentY, var);
>>
>> Which would seem much easier, and should be optimized out the same with inlining. But this might not be practical depending on what "something" is (I'm guessing here it's a lookup or something.)
>>
>> Also, fwiw, I use inout all the time. I think there are specific design patterns and code paths with which it makes complete sense. Example:
>>
>> // Attempt to bring item to the top/head of the linked list.
>> if (!bringToTop(linked_list, item))
>> writefln("Uh oh, %s was not found!", item.toString());
>>
>> I don't think it's ambiguous that linked_list might be modified. Just my opinion. I might prefer "linked_list.bringToTop(item)" if it made sense, though (since that's even harder to misunderstand.)
>>
>> -[Unknown]
>>
>>
>>> Thanks for the maths :)
>>> The maximum are not constant and writing out the place they live would yield to something like:
>>>
>>> array[wrap(something[var].maxX,currentX)][wrap(something[var].maxY,currentY)];
>>>
>>> So the int was a bit of a hack... sorry :)
>>>
>>> About the inout:
>>> How would you do something like this?
>>>
>>> bool something(inout structure struc ,int var){
>>> for (int i=0; i < struc.data[].length; i++){
>>> if(struc.data[i].count==0){
>>> struc.data[i].type=var;
>>> struc.data[i].count=30;
>>> return true;
>>> }
>>> }
>>> return false;
>>> }
>>>
>>>
>>>
>>>
>>>
>>>
>
|
Copyright © 1999-2021 by the D Language Foundation