看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): C語言 額外使用到的函數庫(Library Used): 問題(Question): 輸入一個值 將這個值限制在設定的範圍內 然後輸出 程式碼(Code): double InVal, MinVal, MaxVal; double OpVal; while(InVal > MaxVal) { InVal = InVal - MaxVal + MinVal; } while(InVal < MinVal) { InVal = InVal - MinVal + MaxVal; } OpVal = InVal; 補充說明(Supplement): 這種方法 當InVal的值很大 可是MinVal 和 MaxVal的區間很小的時候 會卡在while迴圈好久 不知道還有沒有什麼更好的寫法可以縮短時間的 補充1:用角度 -360~360來看 360度 = -360度 所以 InVal = 361 MinVal = -360 MaxVal = 360 可以得到 OpVal = -359 因為MinVal不一定為0 所以沒辦法直接用取餘數的方法處理 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.166.80.62 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1469721030.A.390.html
ilikekotomi: 不太懂你的用意 但一般InVal>MaxVal會讓InVal=MaxVal 07/29 00:03
Richun: 把最小值用offset移到0,Range=Max-Min。 07/29 00:46
Richun: InVal=(int)(InVal/Range) + 餘數,不知道負數會怎樣 07/29 00:49
s89227: 用%,外面包一層另外判斷負數? 07/29 00:55
Richun: OpVal = floor((InVal-offset)/Range) + offset; 07/29 01:09
Richun: 這樣應該比原方法快很多,而且正負數通用。剛剛腦殘了。 07/29 01:10
Richun: 上面那串無視吧,半夜腦袋太鈍了... 07/29 01:20
Richun: OpVal = InVal - floor((InVal-Offset)/Range) * Range; 07/29 01:25
Richun: 這樣結果才會是正確的。 07/29 01:28
Richun: floor()在math.h裡。 07/29 01:29
感謝 將程式碼改成 Range = MaxVal - MinVal; OpVal = InVal - floor((InVal - MinVal) / Range) * Range; 確實可以得到一樣的結果 另外 提供用KeilC 跑8051 測試執行時間的結果 輸入區間 [-5, 5] 輸入數值 5 50 500 原始方法執行時間(us) 3.6 14 97.2 新方法執行時間(us) 4.8 7.6 8.0
chuegou: 是說這樣用double感覺很怪 07/29 08:36
原本是用float來處理擷取資料的問題,可是小數點下四位的精準度不足, 所以才改用double來試試看。
noodleT: 有 fmod 浮點數取餘數的函式可以用 07/30 00:15
noodleT: 將角度限定在0~360個人是會這麼寫:fmod(fmod(deg,360)+ 07/30 00:22
noodleT: 360,360) 07/30 00:22
Richun: 可是負數mod正數還是負數,他的MinVal跟InVal可能<0 07/30 01:36
noodleT: 限定在-3~10之間:fmod(fmod(x,13)+13,13)-3 07/30 07:05
這個方法好像也不錯 call了兩次fmod 上面的是call一次floor 等我找個時間再來補充這個方法的執行時間 再來比較看看
noodleT: x 要先加3 07/30 15:25
測試的結果 正確的算式是 Range = MaxVal - MinVal; OpVal = fmod(fmod(InVal - MinVal, Range) + Range, Range) + MinVal; 同樣用KeilC 測試時間 floor的方法 需要 8us fmod的方法 需要 12us ※ 編輯: syatoyan (223.139.136.48), 08/01/2016 18:27:24
LPH66: 這個差距是因為 floor 法做一次除, fmod 法做兩次除 08/01 20:06
LPH66: 除是四則運算裡最花時間的了 08/01 20:06