प्रारूप घंटे और मिनटों में फ्लोट संख्याओं को कैसे योग करें?


14

प्रारूप घंटे और मिनटों में फ्लोट संख्याओं को कैसे योग करें?

उन। यदि ऐसी दो संख्याओं की गणना करें 0.35+3.45तो यह = होना चाहिए 4.20, नहीं3.80

var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]
    
var sum = 0.0;
    
arr.forEach(function(item) {
  console.log(sum);
  sum += parseFloat(item);
});

परिणाम इस तरह होना चाहिए:

0
0.15
0.35
4.20
5.0
7.0
7.30
12.50
13.50
15.30
16.40
19.20
20.20

1
आप तर्क को कैसे परिभाषित करेंगे?
— जुहिल सोमैया

6
तो क्या ०.२ २० मिनट या ०.२ घंटे का प्रतिनिधित्व करता है? 1.0 का मतलब एक घंटा है, या 0.6 का मतलब एक घंटा है?
— Spangle

2
क्षमा करें, इसलिए 1.0 का अर्थ 1 घंटा और 0 मिनट है। उदाहरण के लिए 0.6 और 0.7 का क्या अर्थ है?
— Spangle

2
आपको यहां एक उत्तर मिलेगा: codereview.stackexchange.com/a/109478 । अपनी संख्याओं को स्ट्रिंग्स में बदलें, और फ़ंक्शन में "."उन स्ट्रिंग्स को विभाजित करने के लिए उपयोग करें, न कि ":"।
— गेरार्डो फर्टाडो

6
आप अपने आप को इस तरह के तर्क के साथ उलझाते हैं। 0.5घंटे 30 मिनट होने चाहिए, कुछ भी पूरी तरह से तर्कहीन है। मुझे आशा है कि यह वास्तविक जीवन में एक ग्राहक के लिए नहीं है .. या तो एक निश्चित समय इकाई के फ्लोट मूल्यों के साथ काम करें या आप घंटों / मिनटों को अलग करें। कि जैसे ही आसान।
— कादथ

जवाबों:


7

"पागल" डेटा प्रारूपों से निपटने का सबसे अच्छा तरीका यह है कि पहले उन्हें एक समझदार और आसानी से संसाधित प्रारूप में परिवर्तित किया जाए, आपको परिवर्तित डेटा का उपयोग करके जो कुछ भी करने की ज़रूरत है और अंत में (यदि आपको पूरी तरह से है) परिणामों को वापस बदलना है। मूल प्रारूप।

(बेशक, वास्तविक समाधान पूरी तरह से ऐसे पागल समय अभ्यावेदन का उपयोग बंद करना है। लेकिन यह हमेशा व्यावहारिक नहीं है, उदाहरण के लिए, क्योंकि आपको एक विरासत प्रणाली के साथ इंटरफ़ेस करने की आवश्यकता है जिसे आप बदल नहीं सकते हैं।)

आपके मामले में, आपके डेटा के लिए एक उपयुक्त फलक प्रारूप उदाहरण के लिए एक अभिन्न मिनट होगा। एक बार जब आप अपना डेटा इस प्रारूप में बदल लेते हैं, तो आप उस पर साधारण अंकगणित कर सकते हैं।

// converts a pseudo-float of the form hh.mm into an integer number of minutes
// robust against floating-point roundoff errors, also works for negative numbers
function hhMmToMinutes(x) {
  const hhmm = Math.round(100 * x)  // convert hh.mm -> hhmm
  return 60 * Math.trunc(hhmm / 100) + (hhmm % 100)
}

// convert minutes back to hh.mm pseudo-float format
// use minutesToHhMm(minutes).toFixed(2) if you want trailing zeros
function minutesToHhMm(minutes) {
  return Math.trunc(minutes / 60) + (minutes % 60) / 100
}

const arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]

let sum = 0
console.log( arr.map(hhMmToMinutes).map(x => sum += x).map(minutesToHhMm) )

ध्यान दें कि पहले ऊपर दिया गया रूपांतरण कोड इनपुट को 100 से बढ़ाता है और घंटे और मिनट के हिस्सों को अलग करने से पहले इसे पूर्णांक तक घुमाता है। इनपुट्स को सख्त करने की आवश्यकता को टालते हुए इसे संभावित गोलाई त्रुटियों के साथ इनपुट को मजबूती से संभालना चाहिए।

यहां अतिरिक्त देखभाल करने का कारण यह है क्योंकि 0.01 = 1/100 (और इसके अधिकांश गुणकों) वास्तव में जावास्क्रिप्ट द्वारा उपयोग किए जाने वाले बाइनरी फ्लोटिंग-पॉइंट प्रारूप में बिल्कुल प्रतिनिधित्व योग्य नहीं है । इस प्रकार आपके पास वास्तव में एक जेएस संख्या नहीं हो सकती है जो बिल्कुल बराबर 0.01 होगी - सबसे अच्छा आपके पास एक संख्या हो सकती है जो इतनी करीब है कि इसे स्ट्रिंग में परिवर्तित करना स्वचालित रूप से त्रुटि को छिपाएगा। लेकिन राउंडिंग त्रुटि अभी भी है, और अगर आप ऐसी संख्याओं की तुलना एक सटीक सीमा तक करने की कोशिश करते हैं, तो आप इसे काट सकते हैं। यहाँ एक अच्छा और सरल प्रदर्शन है:

console.log(Math.trunc(100 * 0.29))  // you'd think this would be 29...


7

// We got this after simple addition
// Now we want to change it into 4.2
sample = 3.8

// Now here are the minutes that the float currently shows
minutes = (sample % 1) * 100

// And the hours
hours = Math.floor(sample)

// Here are the number of hours that can be reduced from minutes
AddHours = Math.floor(minutes / 60)

// Adding them to the hours count
hours += AddHours

// Reducing mintues
minutes %= 60

// Finally formatting hour and minutes into your format
final = hours + (minutes / 100.0)
console.log(final)

आप इस तर्क का उपयोग साधारण अंकगणितीय जोड़ करने के बाद कर सकते हैं, यह योग को समय प्रारूप में बदल देगा


2
math.floor(sample/1)सिर्फ के बजाय क्यों math.floor(sample)?
— सेलेबी

2
@selbie, सिर्फ़ इसलिए कि मैंने सबसे पहले केवल जोड़ा sample / 1, मैं हालांकि JS इसे स्वयं फ़्लोर करूंगी क्योंकि भाजक में कोई दशमलव नहीं था (जैसा कि sample / 1.0, JS के इस्तेमाल के बाद काफी लंबा समय है;), लेकिन ऐसा नहीं था इसलिए मैंने जल्दी से googled और जोड़ा; floor, उस को दूर करने के लिए भूल गया। वैसे भी यह इंगित करने के लिए धन्यवाद कि
— लेट्सिन्टेग्रीट

2
आपको यह उल्लेख करना चाहिए कि यह arrपरिणाम में नहीं हर तत्व के लिए किया जाना चाहिए । उदाहरण के लिए, यदि arr = [1.5, 2.5]परिणाम 4इसके बजाय होगा4.4
— टाइटस

1
@ टिट्स, हां मैंने उस हिस्से को याद किया, इसलिए हमें हर एक तत्व से घंटों और मिनटों को प्राप्त करने की आवश्यकता है, फिर उन्हें अलग से जोड़ दें, तभी मेरा दृष्टिकोण उपयोगी होगा।
— लेट्सिन्टेग्रीट

4

यहां आप जावास्क्रिप्ट ईएस 6 में कार्यान्वयन पर जाएं। मैंने प्रत्येक तत्व को लूप किया, और मिनटों को विभाजित किया ., अगर मिनटों की गैर- मौजूदगी है , तो जाँच करें कि 0 घंटे और मिनटों की कुल गणना करें और आवश्यक गणना लागू करें।

const resultObj = [0.35, 3.45].reduce((a, e) => {
  const [hours, minutes] = e.toString().split('.');
  a.h += +hours;
  a.m += (+(minutes.padEnd(2, 0)) || 0); 
  return a;
}, {h: 0, m: 0});


const result = resultObj.h + Math.floor(resultObj.m / 60) + ((resultObj.m % 60) / 100);
console.log(result);


1
के रूप में काम नहीं करेगा, जैसे 0.3 केवल तीन मिनट के रूप में गिना जाएगा, न कि आपके समाधान के साथ 30 मिनट।
— Spangle

3

आपको सब कुछ घंटों या मिनटों में बदलने की आवश्यकता है और फिर गणित करें।

Example: 0.35 + 3.45
Convert 0.35 to Hours Number((35/60).toFixed(2))
= 0.58

Then convert 3hours 45 minutes into hours
= 3 + Number((45/60).toFixed(2))
= 3hours + 0.75 hours
= 3.75

Add the 2 conversions
= 0.58 + 3.75
= 4.33 hours

Convert the 0.33 back to minutes by multiplying by 60
= 4 hours 19.8 minutes ~ 20 mins

Hope that helps!

2

आपको पहले उन्हें घंटों और मिनटों में बदलना होगा

var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4];

function add(arr) {
  var hm = arr
    .map(v => [Math.floor(v), (v % 1).toFixed(2) * 100])  // Map the array to values having [hours, minutes]
    .reduce((t, v) => { //  reduce the array of [h, m] to a single object having total hours and minutes
      t = {
        h: t.h + v[0],
        m: t.m + v[1]
      };
      return t;
    }, {
      h: 0,
      m: 0
    });

  // final result would be = 
  // total hours from above
  // + hours from total minutes (retrived using Math.floor(hm.m / 60)) 
  // + minutes (after converting it to be a decimal part)
  return (parseFloat(hm.h + Math.floor(hm.m / 60)) + parseFloat(((hm.m % 60) / 100).toFixed(2))).toFixed(2);
}

// adding `arr` array
console.log(add(arr));

// adding 0.35+3.45
console.log(add([0.35, 3.45]));


2
दुर्भाग्य से पहले किसी ने इस पर ध्यान नहीं दिया। और यद्यपि शायद सही है, सीखने में कहाँ आ रहा है? अपने समाधान के ओपी से कॉपी और पेस्ट करने से अल्पावधि में बहुत अधिक मदद मिलती है। लेकिन यह एक बुद्धिमान प्रश्न था जो एक बुद्धिमान व्याख्या के योग्य है।
— गेटसेट

2

क्या मुझे पता है कि आप पहला परिणाम 0 क्यों चाहते हैं ? नीचे एक एकल लूप के साथ ऐसा करने का एक तरीका है। टिप्पणियाँ समझाने के लिए कोड में हैं। प्रत्येक लूप के साथ हम मिनट जोड़ते हैं, और यदि वे 60 से अधिक हैं, तो हम एक घंटा जोड़ते हैं, और फिर शेष मिनट प्राप्त करने के लिए % 60 का उपयोग करते हैं । फ्लोट के साथ काम करने के लिए दर्द हो सकता है,

जैसे 1.1 + 2.2 === 3.3 असत्य है

इसलिए मैंने संख्याओं को एक स्ट्रिंग में बदल दिया, और फिर वापस एक इंट में।

var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4];
let hoursTally = 0;
let minutesTally = 0;

for(var i = 0; i < arr.length; i++) {
  // Convert the float to a string, as floats can be a pain to add together
  let time = arr[i].toString().split('.');
  // Tally up the hours.
  hoursTally += parseInt(time[0]);
  // Tally up the minutes;
  let minute = time[1];
  if(minute) {
    // We do this so we add 20 minutes, not 2 minutes
    if(minute.length < 2) {
      minutesTally += parseInt(minute) * 10;
    } else {
      minutesTally += parseInt(minute);
    }
    // If the minutesTally is greater than 60, add an hour to hours
    if(minutesTally >= 60) {
      hoursTally++;
      // Set the minutesTally to be the remainder after dividing by 60
      minutesTally = minutesTally % 60;
    }
  }
  console.log(hoursTally + "." + minutesTally);
}


उह .. हर तरह से .. 2.2 + 1.1 IS 3.3 3h30min के अर्थ के साथ
— eagle275

1
toString().split('.');- अर्घ, वास्तव में?
— user253751

3
@ eagle275 लेकिन संख्या 1.1 + 2.2 3.3 नहीं है जब संख्याएं चल रही हैं। यह 3.3000000000000001 या 3.29999999999999 या कुछ और है। ऐसा इसलिए है क्योंकि 1.1 वास्तव में 1.1 नहीं है और 2.2 वास्तव में 2.2 नहीं है और 3.3 फ्लोटिंग-पॉइंट में वास्तव में 3.3 नहीं है।
— user253751

बालों को विभाजित करना शुरू न करें - मैं इस अजीब नंबर योजना को शुरू से नहीं चुनूंगा ... जब मैंने प्रोग्रामिंग शुरू की थी तो मैंने शायद सब कुछ मिनटों में बदल दिया होगा (या यदि आवश्यक हो तो सेकंड) - उन्हें प्रदर्शन के लिए वापस रूपांतरित करें। लेकिन आजकल मेरी आँखों में datetime नियम
— eagle275

1

const arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]

const reducer = (acc, curr) => {
  acc = `${acc}`.split('.').length > 1 ? acc : `${acc}.0`;
  curr = `${curr}`.split('.').length > 1 ? curr : `${curr}.0`;
  let hours = parseStrAndSum(true, `${acc}`.split('.')[0], `${curr}`.split('.')[0]);
  let minute = parseStrAndSum(false, `${acc}`.split('.')[1], `${curr}`.split('.')[1]);
  hours = parseInt(hours / 1) + parseInt(minute / 60);
  minute = minute % 60;
  console.log(`${acc} + ${curr} = ${hours}.${minute}`);
  return `${hours}.${minute}`;
}

const parseStrAndSum = (is_hours, ...strs) => {
  let result = 0;
  strs.forEach(function(number) {
    if (!is_hours) {
      number = number.length == 1 ? `${number}0` : number;
    }
    result += parseInt(number);
  });
  return result;
};

arr.reduce(reducer);


1
@ एलान 0.15 + 0.2 क्यों =0.17? होना चाहिए0.35
— user12916796

1
उस समय मैंने सोचा था कि दशमलव 0.2 20 मिनट के बजाय दो मिनट के बराबर था। अब जब मैंने कोड समायोजित कर लिया है, तो कृपया फिर से पुष्टि करें।
— इयान

1

एक मापांक को कम करने का मानक तरीका ऐड के बाद घाटे को जोड़ना है अगर एक अतिप्रवाह हुआ था। उदाहरण के लिए आप बाइनरी हार्डवेयर का उपयोग करते हुए बीसीडी जोड़ते हैं।

हालाँकि आप इस तरह से फ़्लोट का उपयोग कर सकते हैं, फिर भी यह सवाल है कि आपको क्या करना चाहिए । मूल रूप से पूर्णांक मात्रा क्या है, इस पर काम करने के लिए फ्लोट नंबरों का उपयोग करने के साथ समस्याएं अच्छी तरह से ज्ञात हैं, और मैं उन्हें यहां रिहा नहीं करने जा रहा हूं।

आम तौर पर, फ्लोट फ्रैक्शंस पर जोड़ 1.0 के मापांक के साथ अनुमानित रूप से काम करता है, अंश का एक अतिप्रवाह पूर्णांक भाग को बढ़ाता है। यदि हम बिंदु को घंटों के रूप में व्याख्या करते हैं। विभाजक को अलग करता है, तो हम चाहते हैं कि अंश 0.6 से अधिक हो जाए। इसके लिए उपयुक्त समय पर 0.4 के घाटे को जोड़ा जाना चाहिए।

function add_float_hours_minutes(a, b)
{
  var trial_sum = a+b;
  // did an actual overflow occur, has the integer part incremented?
  if ( Math.floor(trial_sum) > Math.floor(a)+Math.floor(b) )  {
    trial_sum += 0.4;
  }
  // has the fractional part exceeded its allotted 60 minutes?
  if ( trial_sum-Math.floor(trial_sum) >= 0.6)  {
    trial_sum += 0.4;
  }
  return trial_sum;
}

var arr = [0.15, 0.2, 3.45, 0.4, 2, 0.3, 5.2, 1, 1.4, 1.1, 2.4, 1, 3.4]

var sum = 0.0;

arr.forEach(function(item) {
  console.log(sum);
  // sum += parseFloat(item);
  sum = add_float_hours_minutes(sum, parseFloat(item));
});

जो निम्न आउटपुट का उत्पादन करता है, वह एक गोपन के भीतर सही होता है जिसे ओपी ने पूछा है

0
0.15
0.35
4.2
5.000000000000001
7.000000000000001
7.300000000000001
12.5
13.5
15.3
16.400000000000002
19.2
20.2

मैंने पाठक के लिए एक अभ्यास के रूप में दो दशमलव स्थानों पर अंतिम स्वरूपण छोड़ दिया है। उनके सभी महिमा में 15 अनुगामी अंक इस बात का हिस्सा हैं कि फ्लोट्स का उपयोग करना ऐसा करने का सबसे अच्छा तरीका नहीं है।

इसके अलावा, विचार करें कि क्या होता है जब आप सेकंड, या दिन शामिल करना चाहते हैं। या तो फ्लोट सेकंड के दो या अधिक मानक तरीके, या पूर्णांकों का टपल, अचानक बहुत अधिक समझदार दिखते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.